[FFmpeg-devel] avformat/utils: Fix find_stream_info not considering the extradata it found

Message ID 1469530264-30423-1-git-send-email-anssi.hannula@iki.fi
State Superseded
Headers show

Checks

Context Check Description
andriy/post_check warning test
andr/post_check warning test
yinshiyou/post_check warning test

Commit Message

Anssi Hannula July 26, 2016, 10:51 a.m. UTC
Commit 9200514ad8717c6 ("lavf: replace AVStream.codec with
AVStream.codecpar") merged in commit 6f69f7a8bf6a0d01 changed
avformat_find_stream_info() to put the extradata it got from
st->parser->parser->split() to avctx instead of st->codec.

However, in the same function, the "is stream ready?" check was changed
to check for extradata in st->codecpar instead of st->codec.

Extradata retrieved from split() is therefore not considered anymore,
and avformat_find_stream_info() will therefore needlessly continue
probing in some cases.

Fix that by putting the extradata in st->codecpar, from where it will be
copied to avctx at the end of avformat_find_stream_info() along with
all other parameters.

---

I'm not overly familiar with this code, so review accordingly :)

This can be reproduced e.g. with a simple sample generated with
"ffmpeg -t 20 -f lavfi -i cellauto out.ts", where ffprobe will analyze
for 7 seconds (mpegts max_stream_analyze_duration) instead of the
expected 5 seconds (max_analyze_duration).

The difference will be more dramatic with streams that trigger the
"stop find_stream_info from waiting for more streams when all programs
have received a PMT" check in mpegts demuxer.


 libavformat/utils.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Comments

Michael Niedermayer July 26, 2016, 12:06 p.m. UTC | #1
On Tue, Jul 26, 2016 at 01:51:04PM +0300, Anssi Hannula wrote:
> Commit 9200514ad8717c6 ("lavf: replace AVStream.codec with
> AVStream.codecpar") merged in commit 6f69f7a8bf6a0d01 changed
> avformat_find_stream_info() to put the extradata it got from
> st->parser->parser->split() to avctx instead of st->codec.
> 
> However, in the same function, the "is stream ready?" check was changed
> to check for extradata in st->codecpar instead of st->codec.
> 
> Extradata retrieved from split() is therefore not considered anymore,
> and avformat_find_stream_info() will therefore needlessly continue
> probing in some cases.
> 
> Fix that by putting the extradata in st->codecpar, from where it will be
> copied to avctx at the end of avformat_find_stream_info() along with
> all other parameters.
> 
> ---
> 
> I'm not overly familiar with this code, so review accordingly :)
> 
> This can be reproduced e.g. with a simple sample generated with
> "ffmpeg -t 20 -f lavfi -i cellauto out.ts", where ffprobe will analyze
> for 7 seconds (mpegts max_stream_analyze_duration) instead of the
> expected 5 seconds (max_analyze_duration).
> 
> The difference will be more dramatic with streams that trigger the
> "stop find_stream_info from waiting for more streams when all programs
> have received a PMT" check in mpegts demuxer.

seems to break fate here:
make: *** [fate-iv8-demux] Error 1
make: *** [fate-lmlm4-demux] Error 1
make: *** [fate-nc-demux] Error 1
make: *** [fate-pva-demux] Error 69
make: *** [fate-wtv-demux] Error 1
make: *** [fate-ts-demux] Error 1
make: *** [fate-vc1_sa00040] Error 1
make: *** [fate-vc1_sa00050] Error 1
make: *** [fate-vc1_sa10091] Error 1
make: *** [fate-vc1_sa20021] Error 1
make: *** [fate-vc1_sa10143] Error 1
make: *** [fate-vc1_ilaced_twomv] Error

[...]

Patch

diff --git a/libavformat/utils.c b/libavformat/utils.c
index e5a99ff..392143e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3581,16 +3581,16 @@  FF_ENABLE_DEPRECATION_WARNINGS
         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
             ff_rfps_add_frame(ic, st, pkt->dts);
 #endif
-        if (st->parser && st->parser->parser->split && !avctx->extradata) {
+        if (st->parser && st->parser->parser->split && !st->codecpar->extradata) {
             int i = st->parser->parser->split(avctx, pkt->data, pkt->size);
             if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
-                avctx->extradata_size = i;
-                avctx->extradata      = av_mallocz(avctx->extradata_size +
-                                                   AV_INPUT_BUFFER_PADDING_SIZE);
-                if (!avctx->extradata)
+                st->codecpar->extradata_size = i;
+                st->codecpar->extradata      = av_mallocz(st->codecpar->extradata_size +
+                                                          AV_INPUT_BUFFER_PADDING_SIZE);
+                if (!st->codecpar->extradata)
                     return AVERROR(ENOMEM);
-                memcpy(avctx->extradata, pkt->data,
-                       avctx->extradata_size);
+                memcpy(st->codecpar->extradata, pkt->data,
+                       st->codecpar->extradata_size);
             }
         }