|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|