diff mbox

[FFmpeg-devel] fftools/ffmpeg: Disable copy_ts on timestamp wraparound

Message ID 20190503153607.26133-1-michael@niedermayer.cc
State Accepted
Headers show

Commit Message

Michael Niedermayer May 3, 2019, 3:36 p.m. UTC
This allows handling more than 26.5h of mpeg* input

Fixes: Ticket 7876

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 fftools/ffmpeg.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Panagiotis Malakoudis May 4, 2019, 1:30 p.m. UTC | #1
Στις Παρ, 3 Μαΐ 2019 στις 6:39 μ.μ., ο/η Michael Niedermayer
<michael@niedermayer.cc> έγραψε:
>
> This allows handling more than 26.5h of mpeg* input
>
> Fixes: Ticket 7876
>

I confirm it fixes the case described in the ticket. Will now test it
in realtime environment, so it will take 26,5 hours to report back.
Thank you
Aleksey Skripka May 9, 2019, 12:40 p.m. UTC | #2
Greetings!

> On 3 May 2019, at 18:36, Michael Niedermayer <michael@niedermayer.cc> wrote:
> 
> This allows handling more than 26.5h of mpeg* input
> 
> Fixes: Ticket 7876
> 

not sure how this correlated, but facing my '26.5 hours problem' i found next:

running on plain ts-file is ok:
./ffmpeg -copyts -i 27hours.ts -c copy -f null -

but if this ts-file is wrapped in m3u8, any of this commands:
./ffmpeg  -i 27hours.m3u8 -c copy -f null -
./ffmpeg -copyts -i 27hours.m3u8 -c copy -f null -

fails with:
[mpegts @ 0x2cf6680] DTS 788 < 8589931780 out of order
[hls @ 0x2cf3400] DTS 788 < 8589931780 out of order
[null @ 0x2e28980] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 8589805780 >= -125212
[null @ 0x2e28980] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 8589805780 >= -121612


$ cat 27hours.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:97200
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF: 97200,
27hours.ts
#EXT-X-ENDLIST


ps: ffmpeg = git-master + patch from this mail
Aleksey Skripka Oct. 10, 2019, 10:37 a.m. UTC | #3
Greetings!

Michael,
patch works good for mpegts input, 

but for hls input it works only if add AVFMT_TS_DISCONT to .flags in ff_hls_demuxer structure (libavformat/hls.c).
Is it right way?


> On 3 May 2019, at 18:36, Michael Niedermayer <michael@niedermayer.cc> wrote:
> 
> This allows handling more than 26.5h of mpeg* input
> 
> Fixes: Ticket 7876
> 
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
> fftools/ffmpeg.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 01f04103cf..b58336679d 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -4262,6 +4262,7 @@ static int process_input(int file_index)
>     int ret, thread_ret, i, j;
>     int64_t duration;
>     int64_t pkt_dts;
> +    int disable_discontinuity_correction = copy_ts;
> 
>     is  = ifile->ctx;
>     ret = get_input_packet(ifile, &pkt);
> @@ -4463,10 +4464,20 @@ static int process_input(int file_index)
>         pkt.dts += duration;
> 
>     pkt_dts = av_rescale_q_rnd(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
> +
> +    if (copy_ts && pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
> +        (is->iformat->flags & AVFMT_TS_DISCONT) && ist->st->pts_wrap_bits < 60) {
> +        int64_t wrap_dts = av_rescale_q_rnd(pkt.dts + (1LL<<ist->st->pts_wrap_bits),
> +                                            ist->st->time_base, AV_TIME_BASE_Q,
> +                                            AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
> +        if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10)
> +            disable_discontinuity_correction = 0;
> +    }
> +
>     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
>          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
>          pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
> -        !copy_ts) {
> +        !disable_discontinuity_correction) {
>         int64_t delta   = pkt_dts - ist->next_dts;
>         if (is->iformat->flags & AVFMT_TS_DISCONT) {
>             if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
> -- 
> 2.21.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Michael Niedermayer April 4, 2020, 7:27 p.m. UTC | #4
On Thu, Oct 10, 2019 at 01:37:50PM +0300, Aleksey Skripka wrote:
> Greetings!
> 
> Michael,
> patch works good for mpegts input, 
> 
> but for hls input it works only if add AVFMT_TS_DISCONT to .flags in ff_hls_demuxer structure (libavformat/hls.c).
> Is it right way?

since d6ac6650b911f0957e69545d7fc25be6b7728705 we now have AVFMT_TS_DISCONT
set, so this should be resolved

thx


[...]
Michael Niedermayer April 4, 2020, 8:21 p.m. UTC | #5
On Fri, May 03, 2019 at 05:36:07PM +0200, Michael Niedermayer wrote:
> This allows handling more than 26.5h of mpeg* input
> 
> Fixes: Ticket 7876
> 
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  fftools/ffmpeg.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)

will apply

[...]
Gyan Doshi April 8, 2020, 5:35 p.m. UTC | #6
On 05-04-2020 01:51 am, Michael Niedermayer wrote:
> On Fri, May 03, 2019 at 05:36:07PM +0200, Michael Niedermayer wrote:
>> This allows handling more than 26.5h of mpeg* input
>>
>> Fixes: Ticket 7876
>>
>> Signed-off-by: Michael Niedermayer<michael@niedermayer.cc>
>> ---
>>   fftools/ffmpeg.c | 13 ++++++++++++-
>>   1 file changed, 12 insertions(+), 1 deletion(-)
> will apply

With this, I'm seeing a new offset of max pts being applied to live 
MPEG-TS inputs received over satellite at time of rollover when -copyts 
-start_st_zero is set.

Here is a small snippet as seen in select/aselect filters:

----
[Parsed_select_1 @ 0x55785c522180] n:2857374.000000 
pts:8584574799.000000 t:95384.164433 key:0 interlace_type:B pict_type:B 
scene:nan -> select:1.000000 select_out:0
[Parsed_select_1 @ 0x55785c522180] n:2857375.000000 
pts:8584577802.000000 t:95384.197800 key:0 interlace_type:B pict_type:B 
scene:nan -> select:1.000000 select_out:0
[Parsed_select_1 @ 0x55785c522180] n:2857376.000000 
pts:17174515397.000000 t:190827.948856 key:0 interlace_type:B 
pict_type:P scene:nan -> select:0.000000 select_out:-1
[Parsed_select_1 @ 0x55785c522180] n:2857377.000000 
pts:17174518400.000000 t:190827.982222 key:0 interlace_type:B 
pict_type:B scene:nan -> select:1.000000 select_out:0
----

and

----
[Parsed_aselect_0 @ 0x55785c492340] n:3973138.000000 
pts:4578410637.000000 t:95383.554937 key:1 samples_n:1152 
consumed_samples_n:nan -> select:1.000000 select_out:0
[Parsed_aselect_0 @ 0x55785c492340] n:3973139.000000 
pts:4578411789.000000 t:95383.578938 key:1 samples_n:1152 
consumed_samples_n:nan -> select:1.000000 select_out:0
[Parsed_aselect_0 @ 0x55785c492340] n:3973140.000000 
pts:9159711390.000000 t:190827.320625 key:1 samples_n:1152 
consumed_samples_n:nan -> select:0.000000 select_out:-1
[Parsed_aselect_0 @ 0x55785c492340] n:3973141.000000 
pts:9159712542.000000 t:190827.344625 key:1 samples_n:1152 
consumed_samples_n:nan -> select:1.000000 select_out:0
----

I suspect this is due to

         if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - 
ist->next_dts)/10)
             disable_discontinuity_correction = 0;

as right around the jump, I see

timestamp discontinuity for stream #0:7 (id=131, type=video): 
-95443717689, new offset= 13093624133

and

timestamp discontinuity for stream #0:10 (id=147, type=audio): 
-95443717689, new offset= 108537341822

but I'll need time to check this. Can you investigate?

Thanks,
Gyan
diff mbox

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..b58336679d 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -4262,6 +4262,7 @@  static int process_input(int file_index)
     int ret, thread_ret, i, j;
     int64_t duration;
     int64_t pkt_dts;
+    int disable_discontinuity_correction = copy_ts;
 
     is  = ifile->ctx;
     ret = get_input_packet(ifile, &pkt);
@@ -4463,10 +4464,20 @@  static int process_input(int file_index)
         pkt.dts += duration;
 
     pkt_dts = av_rescale_q_rnd(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+
+    if (copy_ts && pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
+        (is->iformat->flags & AVFMT_TS_DISCONT) && ist->st->pts_wrap_bits < 60) {
+        int64_t wrap_dts = av_rescale_q_rnd(pkt.dts + (1LL<<ist->st->pts_wrap_bits),
+                                            ist->st->time_base, AV_TIME_BASE_Q,
+                                            AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+        if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10)
+            disable_discontinuity_correction = 0;
+    }
+
     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
          pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
-        !copy_ts) {
+        !disable_discontinuity_correction) {
         int64_t delta   = pkt_dts - ist->next_dts;
         if (is->iformat->flags & AVFMT_TS_DISCONT) {
             if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||