diff mbox

[FFmpeg-devel,2/2] lavf/utils: bail early if we don't see any packets in an MPEGTS stream

Message ID 20170502014218.83855-2-rodger.combs@gmail.com
State Superseded
Headers show

Commit Message

Rodger Combs May 2, 2017, 1:42 a.m. UTC
---
 libavformat/utils.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Comments

Matthias Hunstock May 2, 2017, 8:59 a.m. UTC | #1
Am 02.05.2017 um 03:42 schrieb Rodger Combs:
> +    max_empty_analyze_duration = max_analyze_duration;
>      if (!max_analyze_duration) {
> +        max_empty_analyze_duration =
>          max_stream_analyze_duration =
>          max_analyze_duration        = 5*AV_TIME_BASE;
>          max_subtitle_analyze_duration = 30*AV_TIME_BASE;
>          if (!strcmp(ic->iformat->name, "flv"))
>              max_stream_analyze_duration = 90*AV_TIME_BASE;
> -        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts"))
> +        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts")) {
>              max_stream_analyze_duration = 7*AV_TIME_BASE;
> +            max_empty_analyze_duration = 2*AV_TIME_BASE;
> +        }
>      }

What's the origin of "max_empty_analyze_duration = 2*AV_TIME_BASE;", I
mean why 2*timebase and not 1 or 3 or 10 ?

Matthias
Rodger Combs May 2, 2017, 9:07 a.m. UTC | #2
> On May 2, 2017, at 03:59, Matthias Hunstock <atze@fem.tu-ilmenau.de> wrote:
> 
> Am 02.05.2017 um 03:42 schrieb Rodger Combs:
>> +    max_empty_analyze_duration = max_analyze_duration;
>>     if (!max_analyze_duration) {
>> +        max_empty_analyze_duration =
>>         max_stream_analyze_duration =
>>         max_analyze_duration        = 5*AV_TIME_BASE;
>>         max_subtitle_analyze_duration = 30*AV_TIME_BASE;
>>         if (!strcmp(ic->iformat->name, "flv"))
>>             max_stream_analyze_duration = 90*AV_TIME_BASE;
>> -        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts"))
>> +        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts")) {
>>             max_stream_analyze_duration = 7*AV_TIME_BASE;
>> +            max_empty_analyze_duration = 2*AV_TIME_BASE;
>> +        }
>>     }
> 
> What's the origin of "max_empty_analyze_duration = 2*AV_TIME_BASE;", I
> mean why 2*timebase and not 1 or 3 or 10 ?

Same as any of the other constants here, I'd imagine: seemed about right and worked. I'm actually considering changing it to 1, though.
This doesn't apply to subtitle streams, and audio or video streams generally have at least several packets per second, so streams that are actually active _shouldn't_ be affected even with the smaller value.

> 
> Matthias
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Matthias Hunstock May 2, 2017, 9:12 a.m. UTC | #3
Am 02.05.2017 um 11:07 schrieb Rodger Combs:
> This doesn't apply to subtitle streams, and audio or video streams generally have at least several packets per second, so streams that are actually active _shouldn't_ be affected even with the smaller value.

I think this is a dangerous assumption, but it seems using
max_analyze_duration option overrides that max_empty_analyze_duration
default value. So there is a loophole for special cases.

Matthias
Michael Niedermayer May 2, 2017, 2:50 p.m. UTC | #4
On Mon, May 01, 2017 at 08:42:18PM -0500, Rodger Combs wrote:
> ---
>  libavformat/utils.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)

this breaks
./ffmpeg -i  ~/tickets/3673/no-video-stream_cut.flv  -an  -vcodec copy -f framecrc -

https://trac.ffmpeg.org/raw-attachment/ticket/3673/no-video-stream_cut.flv


[...]
diff mbox

Patch

diff --git a/libavformat/utils.c b/libavformat/utils.c
index ba82a766dc..4028d8dbcb 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3505,6 +3505,8 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     int64_t max_analyze_duration = ic->max_analyze_duration;
     int64_t max_stream_analyze_duration;
     int64_t max_subtitle_analyze_duration;
+    int64_t max_empty_analyze_duration;
+    int skip_empty_streams = 0;
     int64_t probesize = ic->probesize;
     int eof_reached = 0;
     int *missing_streams = av_opt_ptr(ic->iformat->priv_class, ic->priv_data, "missing_streams");
@@ -3515,14 +3517,18 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 
     max_stream_analyze_duration = max_analyze_duration;
     max_subtitle_analyze_duration = max_analyze_duration;
+    max_empty_analyze_duration = max_analyze_duration;
     if (!max_analyze_duration) {
+        max_empty_analyze_duration =
         max_stream_analyze_duration =
         max_analyze_duration        = 5*AV_TIME_BASE;
         max_subtitle_analyze_duration = 30*AV_TIME_BASE;
         if (!strcmp(ic->iformat->name, "flv"))
             max_stream_analyze_duration = 90*AV_TIME_BASE;
-        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts"))
+        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts")) {
             max_stream_analyze_duration = 7*AV_TIME_BASE;
+            max_empty_analyze_duration = 2*AV_TIME_BASE;
+        }
     }
 
     if (ic->pb)
@@ -3628,6 +3634,12 @@  FF_ENABLE_DEPRECATION_WARNINGS
             int fps_analyze_framecount = 20;
 
             st = ic->streams[i];
+
+            if (st->codec_info_nb_frames == 0 &&
+                st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
+                skip_empty_streams)
+                continue;
+
             if (!has_codec_parameters(st, NULL))
                 break;
             /* If the timebase is coarse (like the usual millisecond precision
@@ -3791,6 +3803,10 @@  FF_ENABLE_DEPRECATION_WARNINGS
                     av_packet_unref(pkt);
                 break;
             }
+
+            if (t >= max_empty_analyze_duration)
+                skip_empty_streams = 1;
+
             if (pkt->duration) {
                 if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && pkt->pts >= st->start_time) {
                     st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration);