[FFmpeg-cvslog] flvenc: move metadata updates into a single function
ffmpeg | branch: master | Andrew Stone | Fri Nov 7 16:09:09 2014 -0500| [4d0cd5f58c892276716f46f4b2702915e5018215] | committer: Anton Khirnov flvenc: move metadata updates into a single function Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4d0cd5f58c892276716f46f4b2702915e5018215 --- libavformat/flvenc.c | 193 +++--- 1 file changed, 103 insertions(+), 90 deletions(-) diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index cc4c782..7cb1f61 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -60,6 +60,11 @@ typedef struct FLVContext { int64_t filesize_offset; int64_t duration; int64_t delay; ///< first dts delay (needed for AVC & Speex) + +AVCodecContext *audio_enc; +AVCodecContext *video_enc; +double framerate; +AVCodecContext *data_enc; } FLVContext; typedef struct FLVStreamContext { @@ -187,85 +192,14 @@ static void put_amf_bool(AVIOContext *pb, int b) avio_w8(pb, !!b); } -static int flv_write_header(AVFormatContext *s) +static void write_metadata(AVFormatContext *s) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; -AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL; int i, metadata_count = 0; -double framerate = 0.0; int64_t metadata_size_pos, data_size, metadata_count_pos; AVDictionaryEntry *tag = NULL; -for (i = 0; i < s->nb_streams; i++) { -AVCodecContext *enc = s->streams[i]->codec; -FLVStreamContext *sc; -switch (enc->codec_type) { -case AVMEDIA_TYPE_VIDEO: -if (s->streams[i]->avg_frame_rate.den && -s->streams[i]->avg_frame_rate.num) { -framerate = av_q2d(s->streams[i]->avg_frame_rate); -} -if (video_enc) { -av_log(s, AV_LOG_ERROR, - "at most one video stream is supported in flv\n"); -return AVERROR(EINVAL); -} -video_enc = enc; -if (enc->codec_tag == 0) { -av_log(s, AV_LOG_ERROR, "video codec not compatible with flv\n"); -return -1; -} -break; -case AVMEDIA_TYPE_AUDIO: -if (audio_enc) { -av_log(s, AV_LOG_ERROR, - "at most one audio stream is supported in flv\n"); -return AVERROR(EINVAL); -} -audio_enc = enc; -if (get_audio_flags(s, enc) < 0) -return AVERROR_INVALIDDATA; -break; -case AVMEDIA_TYPE_DATA: -if (enc->codec_id != AV_CODEC_ID_TEXT) { -av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n"); -return AVERROR_INVALIDDATA; -} -data_enc = enc; -break; -default: -av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n"); -return -1; -} -avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ - -sc = av_mallocz(sizeof(FLVStreamContext)); -if (!sc) -return AVERROR(ENOMEM); -s->streams[i]->priv_data = sc; -sc->last_ts = -1; -} - -flv->delay = AV_NOPTS_VALUE; - -avio_write(pb, "FLV", 3); -avio_w8(pb, 1); -avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + -FLV_HEADER_FLAG_HASVIDEO * !!video_enc); -avio_wb32(pb, 9); -avio_wb32(pb, 0); - -for (i = 0; i < s->nb_streams; i++) -if (s->streams[i]->codec->codec_tag == 5) { -avio_w8(pb, 8); // message type -avio_wb24(pb, 0); // include flags -avio_wb24(pb, 0); // time stamp -avio_wb32(pb, 0); // reserved -avio_wb32(pb, 11); // size -flv->reserved = 5; -} - /* write meta_tag */ avio_w8(pb, 18);// tag type META metadata_size_pos = avio_tell(pb); @@ -282,57 +216,57 @@ static int flv_write_header(AVFormatContext *s) /* mixed array (hash) with size and string/type/data tuples */ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); metadata_count_pos = avio_tell(pb); -metadata_count = 4 * !!video_enc + - 5 * !!audio_enc + - 1 * !!data_enc + +metadata_count = 4 * !!flv->video_enc + + 5 * !!flv->audio_enc + + 1 * !!flv->data_enc + 2; // +2 for duration and file size avio_wb32(pb, metadata_count); put_amf_string(pb, "duration"); -flv->duration_offset= avio_tell(pb); +flv->duration_offset = avio_tell(pb); // fill in the guessed duration, it'll be correcte
[FFmpeg-cvslog] flvenc: Send new metadata when FLAG_METADATA_UPDATED is set.
ffmpeg | branch: master | Andrew Stone | Fri Nov 7 16:09:10 2014 -0500| [c64f3615118d757dcf76040fe5407bf2b3883206] | committer: Anton Khirnov flvenc: Send new metadata when FLAG_METADATA_UPDATED is set. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c64f3615118d757dcf76040fe5407bf2b3883206 --- libavformat/flvenc.c | 33 +++-- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 7cb1f61..9f39fa7 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -192,7 +192,7 @@ static void put_amf_bool(AVIOContext *pb, int b) avio_w8(pb, !!b); } -static void write_metadata(AVFormatContext *s) +static void write_metadata(AVFormatContext *s, unsigned int ts) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; @@ -204,7 +204,7 @@ static void write_metadata(AVFormatContext *s) avio_w8(pb, 18);// tag type META metadata_size_pos = avio_tell(pb); avio_wb24(pb, 0); // size of data part (sum of all parts below) -avio_wb24(pb, 0); // timestamp +avio_wb24(pb, ts); // timestamp avio_wb32(pb, 0); // reserved /* now data of data_size size */ @@ -373,7 +373,7 @@ static int flv_write_header(AVFormatContext *s) flv->reserved = 5; } -write_metadata(s); +write_metadata(s, 0); for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; @@ -459,6 +459,22 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) else flags_size = 1; +if (flv->delay == AV_NOPTS_VALUE) +flv->delay = -pkt->dts; + +if (pkt->dts < -flv->delay) { +av_log(s, AV_LOG_WARNING, + "Packets are not in the proper order with respect to DTS\n"); +return AVERROR(EINVAL); +} + +ts = pkt->dts + flv->delay; // add delay to force positive dts + +if (s->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) { +write_metadata(s, ts); +s->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED; +} + switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: avio_w8(pb, FLV_TAG_TYPE_VIDEO); @@ -493,17 +509,6 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0) return -1; -if (flv->delay == AV_NOPTS_VALUE) -flv->delay = -pkt->dts; - -if (pkt->dts < -flv->delay) { -av_log(s, AV_LOG_WARNING, - "Packets are not in the proper order with respect to DTS\n"); -return AVERROR(EINVAL); -} - -ts = pkt->dts + flv->delay; // add delay to force positive dts - /* check Speex packet duration */ if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160) av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than " ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] rtmp: support the AMF_DATE tag
ffmpeg | branch: master | Andrew Stone | Mon Aug 31 20:28:42 2015 -0400| [dc926ab518a30880c9e8dd9ec26c74d5e9aa6182] | committer: Michael Niedermayer rtmp: support the AMF_DATE tag Instead of returning EINVAL, which can cause a stream to fail to load, this allows the tag to be passed through to the flv demuxer, where it's summarily ignored. Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dc926ab518a30880c9e8dd9ec26c74d5e9aa6182 --- libavformat/rtmppkt.c |1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index c474fb3..0d693c2 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -440,6 +440,7 @@ int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data); case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data); case AMF_DATA_TYPE_NULL:return 1; +case AMF_DATA_TYPE_DATE:return 11; case AMF_DATA_TYPE_ARRAY: parse_key = 0; case AMF_DATA_TYPE_MIXEDARRAY: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/libvorbisdec: Fix memory leak
ffmpeg | branch: master | Andrew Stone | Tue Sep 8 16:08:29 2015 -0400| [a450ec267225baf431eefadcfacf15879256f363] | committer: Michael Niedermayer avcodec/libvorbisdec: Fix memory leak Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a450ec267225baf431eefadcfacf15879256f363 --- libavcodec/libvorbisdec.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c index 2b22e05..ecf690a 100644 --- a/libavcodec/libvorbisdec.c +++ b/libavcodec/libvorbisdec.c @@ -32,6 +32,8 @@ typedef struct OggVorbisDecContext { ogg_packet op; /**< ogg packet */ } OggVorbisDecContext; +static int oggvorbis_decode_close(AVCodecContext *avccontext); + static int oggvorbis_decode_init(AVCodecContext *avccontext) { OggVorbisDecContext *context = avccontext->priv_data ; uint8_t *p= avccontext->extradata; @@ -110,8 +112,7 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { return 0 ; error: -vorbis_info_clear(&context->vi); -vorbis_comment_clear(&context->vc) ; +oggvorbis_decode_close(avccontext); return ret; } @@ -187,6 +188,8 @@ static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data, static int oggvorbis_decode_close(AVCodecContext *avccontext) { OggVorbisDecContext *context = avccontext->priv_data ; +vorbis_block_clear(&context->vb); +vorbis_dsp_clear(&context->vd); vorbis_info_clear(&context->vi) ; vorbis_comment_clear(&context->vc) ; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] lavf: add AVFormatContext/ AVStream fields for signaling to the user when events happen.
ffmpeg | branch: master | Andrew Stone | Fri Aug 8 13:09:23 2014 -0400| [afbd4b7e093adf6d7a830b32759ca3ba8500363d] | committer: Anton Khirnov lavf: add AVFormatContext/AVStream fields for signaling to the user when events happen. The only flags, for now, indicate if metadata was updated and are set after each call to av_read_frame(). This comes with the caveat that, on stream start, it might not be set properly as packets might be buffered in AVFormatContext.packet_buffer before being given to the user in av_read_frame(). Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=afbd4b7e093adf6d7a830b32759ca3ba8500363d --- doc/APIchanges |4 libavformat/avformat.h | 22 ++ libavformat/version.h |2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6e5242e..feb24cf 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-xx-xx - xxx - lavf 56.01.0 - avformat.h + Add AVFormatContext.event_flags and AVStream.event_flags for signaling to + the user when events happen in the file/stream. + 2014-04-xx - xxx - lavr 2.1.0 - avresample.h Add avresample_convert_frame() and avresample_config(). diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 61ae6fa..5b29145 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -296,6 +296,11 @@ struct AVFormatContext; *- sorting -- a modified version of a tag that should be used for * sorting will have '-sort' appended. E.g. artist="The Beatles", * artist-sort="Beatles, The". + * - Some protocols and demuxers support metadata updates. After a successful + * call to av_read_packet(), AVFormatContext.event_flags or AVStream.event_flags + * will be updated to indicate if metadata changed. In order to detect metadata + * changes on a stream, you need to loop through all streams in the AVFormatContext + * and check their individual event_flags. * * - Demuxers attempt to export metadata in a generic format, however tags *with no generic equivalents are left as they are stored in the container. @@ -798,6 +803,14 @@ typedef struct AVStream { */ intnb_side_data; +/** + * Flags for the user to detect events happening on the stream. Flags must + * be cleared by the user once the event has been handled. + * A combination of AVSTREAM_EVENT_FLAG_*. + */ +int event_flags; +#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. + /* * All fields below this line are not part of the public API. They * may not be used outside of libavformat and can be changed and @@ -1170,6 +1183,15 @@ typedef struct AVFormatContext { * @see AVCodecContext.strict_std_compliance */ int strict_std_compliance; + +/** + * Flags for the user to detect events happening on the file. Flags must + * be cleared by the user once the event has been handled. + * A combination of AVFMT_EVENT_FLAG_*. + */ +int event_flags; +#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. + /* * All fields below this line are not part of the public API. They * may not be used outside of libavformat and can be changed and diff --git a/libavformat/version.h b/libavformat/version.h index 7258d4d..181d268 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 56 -#define LIBAVFORMAT_VERSION_MINOR 0 +#define LIBAVFORMAT_VERSION_MINOR 1 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] AVOption: add support for dictionary types.
ffmpeg | branch: master | Andrew Stone | Thu Jul 31 19:56:34 2014 -0400| [a8c104a511f97e4ea617df73b31737e28a8a5126] | committer: Anton Khirnov AVOption: add support for dictionary types. In order to support metadata being set as an option, it's necessary to be able to set dictionaries as values. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a8c104a511f97e4ea617df73b31737e28a8a5126 --- doc/APIchanges |4 libavutil/opt.c | 54 --- libavutil/opt.h | 31 +++-- libavutil/version.h |2 +- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index feb24cf..66fd1d1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-xx-xx - xxx - lavu 54.02.0 - opt.h + Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support + dictionary types being set as options. + 2014-xx-xx - xxx - lavf 56.01.0 - avformat.h Add AVFormatContext.event_flags and AVStream.event_flags for signaling to the user when events happen in the file/stream. diff --git a/libavutil/opt.c b/libavutil/opt.c index 9f9f1f2..eecc539 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -307,6 +307,24 @@ int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int return 0; } +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags) +{ +void *target_obj; +AVDictionary **dst; +const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + +if (!o || !target_obj) +return AVERROR_OPTION_NOT_FOUND; +if (o->flags & AV_OPT_FLAG_READONLY) +return AVERROR(EINVAL); + +dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset); +av_dict_free(dst); +av_dict_copy(dst, val, 0); + +return 0; +} + int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) { void *dst, *target_obj; @@ -410,6 +428,23 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_ return 0; } +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) +{ +void *target_obj; +AVDictionary *src; +const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + +if (!o || !target_obj) +return AVERROR_OPTION_NOT_FOUND; +if (o->type != AV_OPT_TYPE_DICT) +return AVERROR(EINVAL); + +src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset); +av_dict_copy(out_val, src, 0); + +return 0; +} + int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); @@ -539,7 +574,8 @@ void av_opt_set_defaults(void *s) av_opt_set(s, opt->name, opt->default_val.str, 0); break; case AV_OPT_TYPE_BINARY: -/* Cannot set default for binary */ +case AV_OPT_TYPE_DICT: +/* Cannot set defaults for these types */ break; default: av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); @@ -621,9 +657,21 @@ int av_set_options_string(void *ctx, const char *opts, void av_opt_free(void *obj) { const AVOption *o = NULL; -while ((o = av_opt_next(obj, o))) -if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY) +while ((o = av_opt_next(obj, o))) { +switch (o->type) { +case AV_OPT_TYPE_STRING: +case AV_OPT_TYPE_BINARY: av_freep((uint8_t *)obj + o->offset); +break; + +case AV_OPT_TYPE_DICT: +av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset)); +break; + +default: +break; +} +} } int av_opt_set_dict(void *obj, AVDictionary **options) diff --git a/libavutil/opt.h b/libavutil/opt.h index b90feaa..ac722ee 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -224,6 +224,7 @@ enum AVOptionType{ AV_OPT_TYPE_STRING, AV_OPT_TYPE_RATIONAL, AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length +AV_OPT_TYPE_DICT, AV_OPT_TYPE_CONST = 128, }; @@ -325,7 +326,7 @@ int av_set_options_string(void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep); /** - * Free all string and binary options in obj. + * Free all allocated objects in obj. */ void av_opt_free(void *obj); @@ -491,11 +492,16 @@ const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *pre * AVERROR(ERANGE) if the value is out of
[FFmpeg-cvslog] http: export icecast metadata as an option with name "metadata".
ffmpeg | branch: master | Andrew Stone | Thu Jul 31 19:56:35 2014 -0400| [7601f9412a2d3387617a45966b65b452a632c27a] | committer: Anton Khirnov http: export icecast metadata as an option with name "metadata". Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7601f9412a2d3387617a45966b65b452a632c27a --- libavformat/http.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index b2e07b4..d729faf 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -80,6 +80,7 @@ typedef struct { int icy_metaint; char *icy_metadata_headers; char *icy_metadata_packet; +AVDictionary *metadata; #if CONFIG_ZLIB int compressed; z_stream inflate_stream; @@ -107,6 +108,7 @@ static const AVOption options[] = { { "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, { "icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT }, { "icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT }, +{ "metadata", "metadata read from the bitstream", OFFSET(metadata), AV_OPT_TYPE_DICT, {0}, 0, 0, AV_OPT_FLAG_EXPORT }, { "auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"}, { "none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_NONE }, 0, 0, D | E, "auth_type"}, { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"}, @@ -421,6 +423,8 @@ static int parse_icy(HTTPContext *s, const char *tag, const char *p) int is_first = !s->icy_metadata_headers; int ret; +av_dict_set(&s->metadata, tag, p, 0); + if (s->icy_metadata_headers) len += strlen(s->icy_metadata_headers); @@ -800,6 +804,32 @@ static int http_read_stream_all(URLContext *h, uint8_t *buf, int size) return pos; } +static void update_metadata(HTTPContext *s, char *data) +{ +char *key; +char *val; +char *end; +char *next = data; + +while (*next) { +key = next; +val = strstr(key, "='"); +if (!val) +break; +end = strstr(val, "';"); +if (!end) +break; + +*val = '\0'; +*end = '\0'; +val += 2; + +av_dict_set(&s->metadata, key, val, 0); + +next = end + 2; +} +} + static int store_icy(URLContext *h, int size) { HTTPContext *s = h->priv_data; @@ -828,6 +858,7 @@ static int store_icy(URLContext *h, int size) data[len + 1] = 0; if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0) return ret; +update_metadata(s, data); } s->icy_data_read = 0; remaining= s->icy_metaint; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] http: enable icy metadata by default.
ffmpeg | branch: master | Andrew Stone | Thu Jul 31 19:56:36 2014 -0400| [7e38903b5c86a759549e70647ae42bb22d353b14] | committer: Anton Khirnov http: enable icy metadata by default. It won't hurt servers that don't care about the header, and those that do will include it by default. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7e38903b5c86a759549e70647ae42bb22d353b14 --- Changelog |1 + doc/protocols.texi |2 +- libavformat/http.c |2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index edba289..4f1507a 100644 --- a/Changelog +++ b/Changelog @@ -29,6 +29,7 @@ version : - display matrix export and rotation api - drop avserver, it was unmaintained for years and largely broken - Icecast protocol +- request icecast metadata by default version 10: diff --git a/doc/protocols.texi b/doc/protocols.texi index ec7d924..4957aff 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -119,7 +119,7 @@ Export the MIME type. If set to 1 request ICY (SHOUTcast) metadata from the server. If the server supports this, the metadata has to be retrieved by the application by reading the @option{icy_metadata_headers} and @option{icy_metadata_packet} options. -The default is 0. +The default is 1. @item icy_metadata_headers If the server supports ICY metadata, this contains the ICY-specific HTTP reply diff --git a/libavformat/http.c b/libavformat/http.c index d729faf..98f41c0 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -105,7 +105,7 @@ static const AVOption options[] = { { "multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D | E }, { "post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D | E }, { "mime_type", "export the MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY }, -{ "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, +{ "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D }, { "icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT }, { "icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT }, { "metadata", "metadata read from the bitstream", OFFSET(metadata), AV_OPT_TYPE_DICT, {0}, 0, 0, AV_OPT_FLAG_EXPORT }, ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] Set protocol-level metadata in AVFormatContext any time a packet is read.
ffmpeg | branch: master | Andrew Stone | Thu Jul 31 19:56:37 2014 -0400| [019d3fccc4dcf5c8379112f697ce9eb08edee9b9] | committer: Anton Khirnov Set protocol-level metadata in AVFormatContext any time a packet is read. If any option named "metadata" is set inside the context, it is pulled up to the context and then the option is cleared. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=019d3fccc4dcf5c8379112f697ce9eb08edee9b9 --- libavformat/utils.c |9 + 1 file changed, 9 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index 698fcfe..973ab94 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -892,6 +892,7 @@ static int read_from_packet_buffer(AVPacketList **pkt_buffer, static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) { int ret = 0, i, got_packet = 0; +AVDictionary *metadata = NULL; av_init_packet(pkt); @@ -967,6 +968,14 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (!got_packet && s->parse_queue) ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt); +av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata); +if (metadata) { +s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; +av_dict_copy(&s->metadata, metadata, 0); +av_dict_free(&metadata); +av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN); +} + if (s->debug & FF_FDEBUG_TS) av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", " ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] Expose metadata found in onCuePoint events in .flv files.
ffmpeg | branch: master | Andrew Stone | Mon Aug 11 13:35:09 2014 -0400| [93c04e095dc37ebdab22174e88cfa91e24940866] | committer: Anton Khirnov Expose metadata found in onCuePoint events in .flv files. Currently, only onMetaData is used, but some providers (wrongly) put metadata into onCuePoint events, and it's still nice to be able to use that data. onCuePoint events also present metadata slightly differently than onMetaData events: all metadata is found inside an object called "parameters". In order to extract this metadata, it's easiest to recurse through the object tree and pull out anything found in child objects and put it in the top-level metadata. Reference: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/help.html?content=1404.html Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=93c04e095dc37ebdab22174e88cfa91e24940866 --- libavformat/flvdec.c | 82 ++ 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 034e346..b9391c3 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -438,45 +438,47 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, return -1; } -// only look for metadata values when we are not nested and key != NULL -if (depth == 1 && key) { -acodec = astream ? astream->codec : NULL; -vcodec = vstream ? vstream->codec : NULL; - -if (amf_type == AMF_DATA_TYPE_NUMBER || -amf_type == AMF_DATA_TYPE_BOOL) { -if (!strcmp(key, "duration")) -s->duration = num_val * AV_TIME_BASE; -else if (!strcmp(key, "videodatarate") && vcodec && - 0 <= (int)(num_val * 1024.0)) -vcodec->bit_rate = num_val * 1024.0; -else if (!strcmp(key, "audiodatarate") && acodec && - 0 <= (int)(num_val * 1024.0)) -acodec->bit_rate = num_val * 1024.0; -else if (!strcmp(key, "datastream")) { -AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA); -if (!st) -return AVERROR(ENOMEM); -st->codec->codec_id = AV_CODEC_ID_TEXT; -} else if (flv->trust_metadata) { -if (!strcmp(key, "videocodecid") && vcodec) { -flv_set_video_codec(s, vstream, num_val, 0); -} else if (!strcmp(key, "audiocodecid") && acodec) { -int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET; -flv_set_audio_codec(s, astream, acodec, id); -} else if (!strcmp(key, "audiosamplerate") && acodec) { -acodec->sample_rate = num_val; -} else if (!strcmp(key, "audiosamplesize") && acodec) { -acodec->bits_per_coded_sample = num_val; -} else if (!strcmp(key, "stereo") && acodec) { -acodec->channels = num_val + 1; -acodec->channel_layout = acodec->channels == 2 ? - AV_CH_LAYOUT_STEREO : - AV_CH_LAYOUT_MONO; -} else if (!strcmp(key, "width") && vcodec) { -vcodec->width = num_val; -} else if (!strcmp(key, "height") && vcodec) { -vcodec->height = num_val; +if (key) { +// stream info doesn't live any deeper than the first object +if (depth == 1) { +acodec = astream ? astream->codec : NULL; +vcodec = vstream ? vstream->codec : NULL; + +if (amf_type == AMF_DATA_TYPE_NUMBER || +amf_type == AMF_DATA_TYPE_BOOL) { +if (!strcmp(key, "duration")) +s->duration = num_val * AV_TIME_BASE; +else if (!strcmp(key, "videodatarate") && vcodec && + 0 <= (int)(num_val * 1024.0)) +vcodec->bit_rate = num_val * 1024.0; +else if (!strcmp(key, "audiodatarate") && acodec && + 0 <= (int)(num_val * 1024.0)) +acodec->bit_rate = num_val * 1024.0; +else if (!strcmp(key, "datastream")) { +AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA); +if (!st) +return AVERROR(ENOMEM); +st->codec->codec_id = AV_CODEC_ID_TEXT; +
[FFmpeg-cvslog] flvdec: update AVFormatContext.event_flags with METADATA_UPDATED whenever metadata changes.
ffmpeg | branch: master | Andrew Stone | Tue Aug 12 17:03:52 2014 -0400| [0f789322efa78a672e4c3027e5cc12b8a947043a] | committer: Anton Khirnov flvdec: update AVFormatContext.event_flags with METADATA_UPDATED whenever metadata changes. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0f789322efa78a672e4c3027e5cc12b8a947043a --- libavformat/flvdec.c |1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index b9391c3..56c932c 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -498,6 +498,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, !strcmp(key, "datastream")) return 0; +s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; if (amf_type == AMF_DATA_TYPE_BOOL) { av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val)); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] nutdec: update AVFormatContext.event_flags with STREAM_/ METADATA_UPDATED whenever metadata changes.
ffmpeg | branch: master | Andrew Stone | Tue Aug 12 17:03:53 2014 -0400| [fa3a5dd4dea34baa6bb2f7fe6006fc4b2888f2aa] | committer: Anton Khirnov nutdec: update AVFormatContext.event_flags with STREAM_/METADATA_UPDATED whenever metadata changes. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fa3a5dd4dea34baa6bb2f7fe6006fc4b2888f2aa --- libavformat/nutdec.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 8ec67ae..6c95d55 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -461,9 +461,11 @@ static int decode_info_header(NUTContext *nut) int64_t value, end; char name[256], str_value[1024], type_str[256]; const char *type; +int *event_flags; AVChapter *chapter = NULL; AVStream *st= NULL; AVDictionary **metadata = NULL; +int metadata_flag = 0; end = get_packetheader(nut, bc, 1, INFO_STARTCODE); end += avio_tell(bc); @@ -484,8 +486,13 @@ static int decode_info_header(NUTContext *nut) } else if (stream_id_plus1) { st = s->streams[stream_id_plus1 - 1]; metadata = &st->metadata; -} else +event_flags = &st->event_flags; +metadata_flag = AVSTREAM_EVENT_FLAG_METADATA_UPDATED; +} else { metadata = &s->metadata; +event_flags = &s->event_flags; +metadata_flag = AVFMT_EVENT_FLAG_METADATA_UPDATED; +} for (i = 0; i < count; i++) { get_str(bc, name, sizeof(name)); @@ -521,8 +528,10 @@ static int decode_info_header(NUTContext *nut) continue; } if (metadata && av_strcasecmp(name, "Uses") && -av_strcasecmp(name, "Depends") && av_strcasecmp(name, "Replaces")) +av_strcasecmp(name, "Depends") && av_strcasecmp(name, "Replaces")) { +*event_flags |= metadata_flag; av_dict_set(metadata, name, str_value, 0); +} } } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] mov: update AVFormatContext.event_flags with METADATA_UPDATED whenever metadata changes.
ffmpeg | branch: master | Andrew Stone | Tue Aug 12 17:03:54 2014 -0400| [cc3e88a2b9e7ecf62e4ea1c41ce1623cea67ee96] | committer: Anton Khirnov mov: update AVFormatContext.event_flags with METADATA_UPDATED whenever metadata changes. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cc3e88a2b9e7ecf62e4ea1c41ce1623cea67ee96 --- libavformat/mov.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index fdf9c8d..3ab6776 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -80,6 +80,7 @@ static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, snprintf(buf, sizeof(buf), "%d", current); else snprintf(buf, sizeof(buf), "%d/%d", current, total); +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; av_dict_set(&c->fc->metadata, key, buf, 0); return 0; @@ -96,6 +97,7 @@ static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, avio_r8(pb); snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; av_dict_set(&c->fc->metadata, key, buf, 0); return 0; @@ -107,6 +109,7 @@ static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, char buf[16]; snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; av_dict_set(&c->fc->metadata, key, buf, 0); return 0; @@ -124,6 +127,7 @@ static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, if (genre < 1 || genre > ID3v1_GENRE_MAX) return 0; snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]); +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; av_dict_set(&c->fc->metadata, key, buf, 0); return 0; @@ -242,6 +246,7 @@ static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len) snprintf(key2, sizeof(key2), "%s-%s", key, language); av_dict_set(&c->fc->metadata, key2, buf, 0); } +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; return av_dict_set(&c->fc->metadata, key, buf, 0); } @@ -346,6 +351,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_read(pb, str, str_size); str[str_size] = 0; } +c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; av_dict_set(&c->fc->metadata, key, str, 0); if (*language && strcmp(language, "und")) { snprintf(key2, sizeof(key2), "%s-%s", key, language); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ogg: update event_flags with STREAM_/ METADATA_UPDATED whenever metadata changes.
ffmpeg | branch: master | Andrew Stone | Tue Aug 12 17:03:55 2014 -0400| [db68ef898a3802e51b6f41fd600d0d46d058e3f8] | committer: Anton Khirnov ogg: update event_flags with STREAM_/METADATA_UPDATED whenever metadata changes. Originally, AVFormatContext and a metadata dict were provided to ff_vorbis_comment(), but this presented issues if an AVStream was being updated or the metadata on AVFormatContext wasn't actually being updated. To remedy this, ff_vorbis_stream_comment() explicitly updates a stream's metadata and sets any necessary flags. ff_vorbis_comment() does not modify any flags, and any calls to it that update AVFormatContext's metadata (just a single call) must also update AVFormatContext.event_flags after detecting any metadata changes to the provided dictionary, as signaled by a positive return value. Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db68ef898a3802e51b6f41fd600d0d46d058e3f8 --- libavformat/flacdec.c|5 - libavformat/oggdec.h |3 +++ libavformat/oggparsecelt.c |2 +- libavformat/oggparseflac.c |2 +- libavformat/oggparseogm.c|2 +- libavformat/oggparseopus.c |2 +- libavformat/oggparsespeex.c |2 +- libavformat/oggparsetheora.c |2 +- libavformat/oggparsevorbis.c | 23 +++ 9 files changed, 32 insertions(+), 11 deletions(-) diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 05286c7..e044fd0 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -141,8 +141,11 @@ static int flac_read_header(AVFormatContext *s) if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { AVDictionaryEntry *chmask; -if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1)) { +ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1); +if (ret < 0) { av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); +} else if (ret > 0) { +s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; } /* parse the channels mask if present */ diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index 893c330..b8f0a8b 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -125,6 +125,9 @@ extern const struct ogg_codec ff_vorbis_codec; int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size, int parse_picture); +int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, + const uint8_t *buf, int size); + static inline int ogg_find_stream (struct ogg * ogg, int serial) { diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c index 47ccc6f..7084e76 100644 --- a/libavformat/oggparsecelt.c +++ b/libavformat/oggparsecelt.c @@ -79,7 +79,7 @@ static int celt_header(AVFormatContext *s, int idx) } else if (priv && priv->extra_headers_left) { /* Extra headers (vorbiscomment) */ -ff_vorbis_comment(s, &st->metadata, p, os->psize, 1); +ff_vorbis_stream_comment(s, st, p, os->psize); priv->extra_headers_left--; return 1; } else { diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c index 7808aad..f9c15f9 100644 --- a/libavformat/oggparseflac.c +++ b/libavformat/oggparseflac.c @@ -69,7 +69,7 @@ flac_header (AVFormatContext * s, int idx) avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) { -ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 4, os->psize - 4, 1); +ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 4, os->psize - 4); } return 1; diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c index 74d9e10..913282a 100644 --- a/libavformat/oggparseogm.c +++ b/libavformat/oggparseogm.c @@ -97,7 +97,7 @@ ogm_header(AVFormatContext *s, int idx) } else if (bytestream2_peek_byte(&p) == 3) { bytestream2_skip(&p, 7); if (bytestream2_get_bytes_left(&p) > 1) -ff_vorbis_comment(s, &st->metadata, p.buffer, bytestream2_get_bytes_left(&p) - 1, 1); +ff_vorbis_stream_comment(s, st, p.buffer, bytestream2_get_bytes_left(&p) - 1); } return 1; diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index cfdf35d..5931ab5 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -74,7 +74,7 @@ static int opus_header(AVFormatContext *avf, int idx) if (priv->need_comments) { if (os->psize < 8 || memcmp(packet, "OpusTags", 8)) return AVERROR_INVALIDDATA; -ff_vorbis_comment(avf, &st->metadata,
[FFmpeg-cvslog] Revert "lavf: eliminate ff_get_audio_frame_size()"
ffmpeg | branch: release/2.4 | Andrew Stone | Mon Aug 18 17:28:23 2014 -0400| [04361427e65a687469a3bb0859971292d2dc11e4] | committer: Anton Khirnov Revert "lavf: eliminate ff_get_audio_frame_size()" This reverts commit 30e50c50274f88f0f5ae829f401cd3c7f5266719. The original commit broke the ability to stream AAC over HTTP/Icecast. It looks like avformat_find_stream_info() gets stuck in an infinite loop, never hitting AVFormatContext.max_analyze_duration since duration is never set for any of the packets. Example stream: http://listen.classicrocklounge.com:8000/aac64 Signed-off-by: Anton Khirnov > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=04361427e65a687469a3bb0859971292d2dc11e4 --- libavformat/internal.h |2 ++ libavformat/utils.c| 23 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index 9921ce1..2824436 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -326,6 +326,8 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, AVCodecParserContext *pc, AVPacket *pkt); +int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux); + unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id); enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); diff --git a/libavformat/utils.c b/libavformat/utils.c index 4cc246d..973ab94 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -454,6 +454,27 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) /**/ /** + * Get the number of samples of an audio frame. Return -1 on error. + */ +int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux) +{ +int frame_size; + +/* give frame_size priority if demuxing */ +if (!mux && enc->frame_size > 1) +return enc->frame_size; + +if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0) +return frame_size; + +/* Fall back on using frame_size if muxing. */ +if (enc->frame_size > 1) +return enc->frame_size; + +return -1; +} + +/** * Return the frame duration in seconds. Return 0 if not available. */ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, @@ -488,7 +509,7 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, } break; case AVMEDIA_TYPE_AUDIO: -frame_size = av_get_audio_frame_duration(st->codec, pkt->size); +frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 0); if (frame_size <= 0 || st->codec->sample_rate <= 0) break; *pnum = frame_size; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog