diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-01-02 09:01:02 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2012-01-03 14:58:21 +0100 |
commit | 212fd3a1f1121a9db20c478f1fccf15e8bb53c94 (patch) | |
tree | b032a2fdd08eb8ef01447696088f1f3fb6051f0f | |
parent | 02e8f4272c99f745eb201622c07b0613a8cd22ae (diff) | |
download | ffmpeg-212fd3a1f1121a9db20c478f1fccf15e8bb53c94.tar.gz |
lavf: flush decoders in avformat_find_stream_info().
This means that avformat_find_stream_info() now works properly with
multiple threads, so there's no need to force thread count to 1.
-rw-r--r-- | libavformat/utils.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index 163d602a53..db028780ff 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2126,7 +2126,7 @@ static int has_decode_delay_been_guessed(AVStream *st) static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { AVCodec *codec; - int got_picture, ret = 0; + int got_picture = 1, ret = 0; AVFrame picture; AVPacket pkt = *avpkt; @@ -2139,7 +2139,8 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option return ret; } - while (pkt.size > 0 && ret >= 0 && + while ((pkt.size > 0 || (!pkt.data && got_picture)) && + ret >= 0 && (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st) || (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) { @@ -2268,14 +2269,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int i, count, ret, read_size, j; AVStream *st; AVPacket pkt1, *pkt; - AVDictionary *one_thread_opt = NULL; int64_t old_offset = avio_tell(ic->pb); int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those - /* this function doesn't flush the decoders, so force thread count - * to 1 to fix behavior when thread count > number of frames in the file */ - av_dict_set(&one_thread_opt, "threads", "1", 0); - for(i=0;i<ic->nb_streams;i++) { AVCodec *codec; st = ic->streams[i]; @@ -2297,21 +2293,15 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) assert(!st->codec->codec); codec = avcodec_find_decoder(st->codec->codec_id); - /* this function doesn't flush the decoders, so force thread count - * to 1 to fix behavior when thread count > number of frames in the file */ - if (options) - av_dict_set(&options[i], "threads", "1", 0); - /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] : &one_thread_opt); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] - : &one_thread_opt); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); } } @@ -2377,10 +2367,22 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) continue; if (ret < 0) { - /* EOF or error */ + /* EOF or error*/ + AVPacket empty_pkt = { 0 }; + int err; + av_init_packet(&empty_pkt); + ret = -1; /* we could not have all the codec parameters before EOF */ for(i=0;i<ic->nb_streams;i++) { st = ic->streams[i]; + + /* flush the decoders */ + while ((err = try_decode_frame(st, &empty_pkt, + (options && i < orig_nb_streams) ? + &options[i] : NULL)) >= 0) + if (has_codec_parameters(st->codec)) + break; + if (!has_codec_parameters(st->codec)){ char buf[256]; avcodec_string(buf, sizeof(buf), st->codec, 0); @@ -2450,8 +2452,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) least one frame of codec data, this makes sure the codec initializes the channel configuration and does not only trust the values from the container. */ - try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] - : &one_thread_opt); + try_decode_frame(st, pkt, (options && i < orig_nb_streams ) ? &options[i] : NULL); st->codec_info_nb_frames++; count++; @@ -2561,7 +2562,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ic->streams[i]->codec->thread_count = 0; av_freep(&ic->streams[i]->info); } - av_dict_free(&one_thread_opt); return ret; } |