[FFmpeg-devel] [PATCH] avformat/segment: fix the duration error of use output_ts_offset

Michael Niedermayer michael at niedermayer.cc
Sun Sep 11 13:22:49 EEST 2016


On Sat, Sep 10, 2016 at 06:47:38PM +0800, Steven Liu wrote:
> 2016-09-10 13:55 GMT+08:00 Aman Gupta <ffmpeg at tmm1.net>:
> 
> > I confirmed your latest patch fixes the issue and is working as expected
> > now.
> >
> > Thank you!
> >
> > Aman
> >
> > On Sat, Sep 10, 2016 at 7:00 AM, Steven Liu <lingjiujianke at gmail.com>
> > wrote:
> >
> >>
> >> Steven Liu <lingjiujianke at gmail.com>于2016年9月9日 周五下午7:59写道:
> >>
> >>> 2016-09-09 16:33 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
> >>>
> >>>>
> >>>>
> >>>> 2016-09-09 16:10 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
> >>>>
> >>>>>
> >>>>>
> >>>>> 2016-09-09 15:33 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:
> >>>>>
> >>>>>>
> >>>>>>
> >>>>>> 2016-09-09 15:28 GMT+08:00 Aman Gupta <aman at tmm1.net>:
> >>>>>>
> >>>>>>> I tried your patch and TARGETDURATION is fixed, but it is still
> >>>>>>> creating some segments which are only 0.2s instead of 2s.
> >>>>>>>
> >>>>>>> Aman
> >>>>>>>
> >>>>>>> On Thu, Sep 8, 2016 at 8:14 PM, Steven Liu <lingjiujianke at gmail.com>
> >>>>>>> wrote:
> >>>>>>>
> >>>>>>>> This patch can merge with 1da00be009aa74400042bf470b9a5ffbd82a1c5e
> >>>>>>>> i have checked this modify:
> >>>>>>>>
> >>>>>>>> ./ffmpeg -i ~/facebook.mp4 -c copy -f segment -segment_time 2
> >>>>>>>> -output_ts_offset 80 -segment_list output-test.m3u8 -v debug
> >>>>>>>> output-test-%03d.ts
> >>>>>>>>
> >>>>>>>> #EXTM3U
> >>>>>>>> #EXT-X-VERSION:3
> >>>>>>>> #EXT-X-MEDIA-SEQUENCE:0
> >>>>>>>> #EXT-X-ALLOW-CACHE:YES
> >>>>>>>> #EXT-X-TARGETDURATION:10
> >>>>>>>> #EXTINF:4.120000,
> >>>>>>>> output-test-000.ts
> >>>>>>>> #EXTINF:7.840000,
> >>>>>>>> output-test-001.ts
> >>>>>>>> #EXTINF:4.200000,
> >>>>>>>> output-test-002.ts
> >>>>>>>> #EXTINF:2.920000,
> >>>>>>>> output-test-003.ts
> >>>>>>>> #EXTINF:1.840000,
> >>>>>>>> output-test-004.ts
> >>>>>>>> #EXTINF:2.240000,
> >>>>>>>> output-test-005.ts
> >>>>>>>> #EXTINF:2.000000,
> >>>>>>>> output-test-006.ts
> >>>>>>>> #EXTINF:3.560000,
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> [root at localhost linux]# ffmpeg -i output-test.m3u8
> >>>>>>>> ffmpeg version N-80917-ga1a240b Copyright (c) 2000-2016 the FFmpeg
> >>>>>>>> developers
> >>>>>>>>   built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
> >>>>>>>>   configuration: --prefix=/usr/ --libdir=/usr/lib64
> >>>>>>>> --enable-libx264 --enable-libfaac --enable-gpl --enable-nonfree
> >>>>>>>>   libavutil      55. 28.100 / 55. 28.100
> >>>>>>>>   libavcodec     57. 48.102 / 57. 48.102
> >>>>>>>>   libavformat    57. 41.100 / 57. 41.100
> >>>>>>>>   libavdevice    57.  0.102 / 57.  0.102
> >>>>>>>>   libavfilter     6. 47.100 /  6. 47.100
> >>>>>>>>   libswscale      4.  1.100 /  4.  1.100
> >>>>>>>>   libswresample   2.  1.100 /  2.  1.100
> >>>>>>>>   libpostproc    54.  0.100 / 54.  0.100
> >>>>>>>> Input #0, hls,applehttp, from 'output-test.m3u8':
> >>>>>>>>   Duration: 00:03:21.04, start: 81.400000, bitrate: 0 kb/s
> >>>>>>>>   Program 0
> >>>>>>>>     Metadata:
> >>>>>>>>       variant_bitrate : 0
> >>>>>>>>     Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B),
> >>>>>>>> yuv420p, 720x528 [SAR 1:1 DAR 15:11], 25 fps, 25 tbr, 90k tbn, 50 tbc
> >>>>>>>>     Stream #0:1: Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz,
> >>>>>>>> 5.1(side), fltp, 384 kb/s
> >>>>>>>> At least one output file must be specified
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> [root at localhost linux]# ffmpeg -i output-test-000.ts -i
> >>>>>>>> output-test-001.ts
> >>>>>>>> ffmpeg version N-80917-ga1a240b Copyright (c) 2000-2016 the FFmpeg
> >>>>>>>> developers
> >>>>>>>>   built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
> >>>>>>>>   configuration: --prefix=/usr/ --libdir=/usr/lib64
> >>>>>>>> --enable-libx264 --enable-libfaac --enable-gpl --enable-nonfree
> >>>>>>>>   libavutil      55. 28.100 / 55. 28.100
> >>>>>>>>   libavcodec     57. 48.102 / 57. 48.102
> >>>>>>>>   libavformat    57. 41.100 / 57. 41.100
> >>>>>>>>   libavdevice    57.  0.102 / 57.  0.102
> >>>>>>>>   libavfilter     6. 47.100 /  6. 47.100
> >>>>>>>>   libswscale      4.  1.100 /  4.  1.100
> >>>>>>>>   libswresample   2.  1.100 /  2.  1.100
> >>>>>>>>   libpostproc    54.  0.100 / 54.  0.100
> >>>>>>>> Input #0, mpegts, from 'output-test-000.ts':
> >>>>>>>>   Duration: 00:00:04.12, start: 81.400000, bitrate: 1299 kb/s
> >>>>>>>>   Program 1
> >>>>>>>>     Metadata:
> >>>>>>>>       service_name    : Service01
> >>>>>>>>       service_provider: FFmpeg
> >>>>>>>>     Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] /
> >>>>>>>> 0x001B), yuv420p, 720x528 [SAR 1:1 DAR 15:11], 25 fps, 25 tbr, 90k tbn, 50
> >>>>>>>> tbc
> >>>>>>>>     Stream #0:1[0x101](und): Audio: ac3 ([129][0][0][0] / 0x0081),
> >>>>>>>> 48000 Hz, 5.1(side), fltp, 384 kb/s
> >>>>>>>> Input #1, mpegts, from 'output-test-001.ts':
> >>>>>>>>   Duration: 00:00:07.90, start: 85.464000, bitrate: 1679 kb/s
> >>>>>>>>   Program 1
> >>>>>>>>     Metadata:
> >>>>>>>>       service_name    : Service01
> >>>>>>>>       service_provider: FFmpeg
> >>>>>>>>     Stream #1:0[0x100]: Video: h264 (High) ([27][0][0][0] /
> >>>>>>>> 0x001B), yuv420p, 720x528 [SAR 1:1 DAR 15:11], 25 fps, 25 tbr, 90k tbn, 50
> >>>>>>>> tbc
> >>>>>>>>     Stream #1:1[0x101](und): Audio: ac3 ([129][0][0][0] / 0x0081),
> >>>>>>>> 48000 Hz, 5.1(side), fltp, 384 kb/s
> >>>>>>>> At least one output file must be specified
> >>>>>>>> [root at localhost linux]#
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> this commit is used for fix commit 1da00be009aa74400042bf470b9a5f
> >>>>>>>> fbd82a1c5e
> >>>>>>>> because the option initial_offset will deprecated
> >>>>>>>>
> >>>>>>>> Signed-off-by: Steven Liu <lingjiujianke at gmail.com>
> >>>>>>>> ---
> >>>>>>>>  libavformat/segment.c |    5 +++++
> >>>>>>>>  1 files changed, 5 insertions(+), 0 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/libavformat/segment.c b/libavformat/segment.c
> >>>>>>>> index 33a5cf0..252f8b1 100644
> >>>>>>>> --- a/libavformat/segment.c
> >>>>>>>> +++ b/libavformat/segment.c
> >>>>>>>> @@ -885,6 +885,11 @@ calc_times:
> >>>>>>>>          av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet
> >>>>>>>> stream:%d pts:%s pts_time:%s frame:%d\n",
> >>>>>>>>                 seg->avf->filename, pkt->stream_index,
> >>>>>>>>                 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts,
> >>>>>>>> &st->time_base), seg->frame_count);
> >>>>>>>> +        seg->cut_pending = 0;
> >>>>>>>> +        seg->cur_entry.index = seg->segment_idx +
> >>>>>>>> seg->segment_idx_wrap * seg->segment_idx_wrap_nb;
> >>>>>>>> +        seg->cur_entry.start_time = (double)pkt->pts *
> >>>>>>>> av_q2d(st->time_base);
> >>>>>>>> +        seg->cur_entry.start_pts = av_rescale_q(pkt->pts,
> >>>>>>>> st->time_base, AV_TIME_BASE_Q);
> >>>>>>>> +        seg->cur_entry.end_time = seg->cur_entry.start_time;
> >>>>>>>>      }
> >>>>>>>>
> >>>>>>>>      av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s
> >>>>>>>> pts_time:%s dts:%s dts_time:%s",
> >>>>>>>> --
> >>>>>>>> 1.7.1
> >>>>>>>>
> >>>>>>>
> >>>>>>> ok, let me try your command line
> >>>>>>
> >>>>>>
> >>>>> ......
> >>>>> it's reproduced when encode by default(video:mpeg2video  audio: mp2)
> >>>>>
> >>>>> Ha, interesting,
> >>>> /ffmpeg -ss 20 -i ~/Movies/objectC/facebook.mp4 -g 50 -f segment
> >>>>  -segment_time 2 -segment_start_number 10 -output_ts_offset 40
> >>>> -segment_list output-test.m3u8 -v debug output-test-%03d.ts
> >>>>
> >>>> no problem
> >>>>
> >>>> ./ffmpeg -ss 20 -i ~/Movies/objectC/facebook.mp4 -c:v mpeg2video -g 50
> >>>> -f segment  -segment_time 2 -segment_start_number 10 -output_ts_offset 40
> >>>> -segment_list output-test.m3u8 -v debug output-test-%03d.ts
> >>>>
> >>>> no problem
> >>>>
> >>>> ./ffmpeg -ss 20 -i ~/Movies/objectC/facebook.mp4 -c:v libx264 -g 50 -f
> >>>> segment  -segment_time 2 -segment_start_number 10 -output_ts_offset 40
> >>>> -segment_list output-test.m3u8 -v debug output-test-%03d.ts
> >>>>
> >>>> no problem
> >>>>
> >>>>
> >>>> ./ffmpeg -ss 20 -i ~/Movies/objectC/facebook.mp4 -c copy -f segment
> >>>>  -segment_time 2 -segment_start_number 10 -output_ts_offset 40
> >>>> -segment_list output-test.m3u8 -v debug output-test-%03d.ts
> >>>>
> >>>> no problem
> >>>>
> >>>>
> >>>> ./ffmpeg -ss 20 -i ~/Movies/objectC/facebook.mp4 -f segment
> >>>>  -segment_time 2 -segment_start_number 10 -output_ts_offset 40
> >>>> -segment_list output-test.m3u8 -v debug output-test-%03d.ts
> >>>>
> >>>> reproduced
> >>>>
> >>>>
> >>>>
> >>> patch update, no problem now.
> >>>
> >>> ./ffmpeg -ss 40 -i ~/Movies/objectC/facebook.mp4 -f segment
> >>>  -segment_time 2 -output_ts_offset 40 -segment_list output-test.m3u8
> >>> -segment_start_number 10 -t 12 output-test-%03d.ts
> >>>
> >>> no problem
> >>>
> >>> #EXTM3U
> >>> #EXT-X-VERSION:3
> >>> #EXT-X-MEDIA-SEQUENCE:10
> >>> #EXT-X-ALLOW-CACHE:YES
> >>> #EXT-X-TARGETDURATION:3
> >>> #EXTINF:2.400000,
> >>> output-test-010.ts
> >>> #EXTINF:2.040000,
> >>> output-test-011.ts
> >>> #EXTINF:1.920000,
> >>> output-test-012.ts
> >>> #EXTINF:1.920000,
> >>> output-test-013.ts
> >>> #EXTINF:1.920000,
> >>> output-test-014.ts
> >>> #EXTINF:1.800000,
> >>> output-test-015.ts
> >>> #EXT-X-ENDLIST
> >>>
> >>>
> >>>
> >>> this commit is used for fix commit 1da00be009aa74400042bf470b9a5f
> >>> fbd82a1c5e
> >>> because the option initial_offset will deprecated
> >>>
> >>> Signed-off-by: Steven Liu <lingjiujianke at gmail.com>
> >>> ---
> >>>  libavformat/segment.c | 12 +++++++++++-
> >>>  1 file changed, 11 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/libavformat/segment.c b/libavformat/segment.c
> >>> index 33a5cf0..74ffe03 100644
> >>> --- a/libavformat/segment.c
> >>> +++ b/libavformat/segment.c
> >>> @@ -101,6 +101,7 @@ typedef struct SegmentContext {
> >>>      char *times_str;       ///< segment times specification string
> >>>      int64_t *times;        ///< list of segment interval specification
> >>>      int nb_times;          ///< number of elments in the times array
> >>> +    int64_t init_time;     ///< first segment start time
> >>>
> >>>      char *frames_str;      ///< segment frame numbers specification
> >>> string
> >>>      int *frames;           ///< list of frame number specification
> >>> @@ -642,6 +643,7 @@ static int seg_init(AVFormatContext *s)
> >>>      int ret;
> >>>      int i;
> >>>
> >>> +    seg->init_time = 0;
> >>>      seg->segment_count = 0;
> >>>      if (!seg->write_header_trailer)
> >>>          seg->individual_header_trailer = 0;
> >>> @@ -837,7 +839,11 @@ calc_times:
> >>>              }
> >>>              seg->last_val = wrapped_val;
> >>>          } else {
> >>> -            end_pts = seg->time * (seg->segment_count + 1);
> >>> +            if (seg->init_time == 0) {
> >>> +                seg->init_time = av_rescale_q(pkt->pts, st->time_base,
> >>> AV_TIME_BASE_Q);
> >>> +            } else {
> >>> +                end_pts = seg->time * (seg->segment_count + 1) +
> >>> seg->init_time;
> >>> +            }
> >>>          }
> >>>      }
> >>>
> >>> @@ -885,6 +891,10 @@ calc_times:
> >>>          av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet
> >>> stream:%d pts:%s pts_time:%s frame:%d\n",
> >>>                 seg->avf->filename, pkt->stream_index,
> >>>                 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts,
> >>> &st->time_base), seg->frame_count);
> >>> +        seg->cur_entry.index = seg->segment_idx + seg->segment_idx_wrap
> >>> * seg->segment_idx_wrap_nb;
> >>> +        seg->cur_entry.start_time = (double)pkt->pts *
> >>> av_q2d(st->time_base);
> >>> +        seg->cur_entry.start_pts = av_rescale_q(pkt->pts,
> >>> st->time_base, AV_TIME_BASE_Q);
> >>> +        seg->cur_entry.end_time = seg->cur_entry.start_time;
> >>>      }
> >>>
> >>>      av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s
> >>> pts_time:%s dts:%s dts_time:%s",
> >>> --
> >>> 2.7.4 (Apple Git-66)
> >>>
> >>> maybe have a bug, I'll fix it
> >> When use all the output_ts_offset and initial_offset it will wrong result.
> >>
> >
> > patch update!
> 
> Ignore the initial_offset if use all the initial_offset and
> output_ts_offset.
> 
> this commit is used for fix commit 1da00be009aa74400042bf470b9a5ffbd82a1c5e
> because the option initial_offset will deprecated
> 
> Reviewed-by:  Aman Gupta <ffmpeg at tmm1.net>
> Signed-off-by: Steven Liu <liuqi at gosun.com>
> ---
>  libavformat/segment.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 33a5cf0..73d6574 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -101,6 +101,7 @@ typedef struct SegmentContext {
>      char *times_str;       ///< segment times specification string
>      int64_t *times;        ///< list of segment interval specification
>      int nb_times;          ///< number of elments in the times array
> +    int64_t init_time;     ///< first segment start time
> 
>      char *frames_str;      ///< segment frame numbers specification string
>      int *frames;           ///< list of frame number specification
> @@ -642,6 +643,7 @@ static int seg_init(AVFormatContext *s)
>      int ret;
>      int i;
> 
> +    seg->init_time = AV_NOPTS_VALUE;
>      seg->segment_count = 0;
>      if (!seg->write_header_trailer)
>          seg->individual_header_trailer = 0;
> @@ -837,7 +839,12 @@ calc_times:
>              }
>              seg->last_val = wrapped_val;
>          } else {
> -            end_pts = seg->time * (seg->segment_count + 1);
> +            if (seg->init_time == AV_NOPTS_VALUE) {
> +                seg->init_time = av_rescale_q(pkt->pts, st->time_base,
> AV_TIME_BASE_Q);
> +                seg->initial_offset = 0;
> +            } else {
> +                end_pts = seg->time * (seg->segment_count + 1) +
> seg->init_time;
> +            }
>          }
>      }
> 
> @@ -885,6 +892,10 @@ calc_times:
>          av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet
> stream:%d pts:%s pts_time:%s frame:%d\n",
>                 seg->avf->filename, pkt->stream_index,
>                 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts,
> &st->time_base), seg->frame_count);
> +        seg->cur_entry.index = seg->segment_idx + seg->segment_idx_wrap *
> seg->segment_idx_wrap_nb;
> +        seg->cur_entry.start_time = (double)pkt->pts *
> av_q2d(st->time_base);
> +        seg->cur_entry.start_pts = av_rescale_q(pkt->pts, st->time_base,
> AV_TIME_BASE_Q);
> +        seg->cur_entry.end_time = seg->cur_entry.start_time;
>      }
> 
>      av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s
> pts_time:%s dts:%s dts_time:%s",
> -- 
> 2.7.4 (Apple Git-66)

>  segment.c |   13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 779c7a2b00c7c3c93e04b327707db949fe8d168a  0001-avformat-segment-fix-the-duration-error-of-use-outpu.patch
> From c384b0a2d897461bb3ee232555d2c1c3904c5034 Mon Sep 17 00:00:00 2001
> From: Steven Liu <lingjiujianke at gmail.com>
> Date: Sat, 10 Sep 2016 18:40:22 +0800
> Subject: [PATCH] avformat/segment: fix the duration error of use
>  output_ts_offset
> 
> this commit is used for fix commit 1da00be009aa74400042bf470b9a5ffbd82a1c5e
> because the option initial_offset will deprecated
> 
> Reviewed-by:  Aman Gupta <ffmpeg at tmm1.net>
> Signed-off-by: Steven Liu <liuqi at gosun.com>
> ---
>  libavformat/segment.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 33a5cf0..73d6574 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -101,6 +101,7 @@ typedef struct SegmentContext {
>      char *times_str;       ///< segment times specification string
>      int64_t *times;        ///< list of segment interval specification
>      int nb_times;          ///< number of elments in the times array
> +    int64_t init_time;     ///< first segment start time
>  
>      char *frames_str;      ///< segment frame numbers specification string
>      int *frames;           ///< list of frame number specification
> @@ -642,6 +643,7 @@ static int seg_init(AVFormatContext *s)
>      int ret;
>      int i;
>  
> +    seg->init_time = AV_NOPTS_VALUE;
>      seg->segment_count = 0;
>      if (!seg->write_header_trailer)
>          seg->individual_header_trailer = 0;
> @@ -837,7 +839,12 @@ calc_times:
>              }
>              seg->last_val = wrapped_val;
>          } else {
> -            end_pts = seg->time * (seg->segment_count + 1);
> +            if (seg->init_time == AV_NOPTS_VALUE) {
> +                seg->init_time = av_rescale_q(pkt->pts, st->time_base, AV_TIME_BASE_Q);

> +                seg->initial_offset = 0;

does this not ignore user set initial_offset and would break if the
user did set the option?


> +            } else {

> +                end_pts = seg->time * (seg->segment_count + 1) + seg->init_time;

why is this in the else and not always ?


also this patch changes many cases where neither initial_offset nor
output_ts_offset is set
is this intended?

also i think we have some misunderstanding and confusion here

at least iam a bit confused ;)

IIRC aman wanted to add initial_offset to hlsenc, i asked if it is
redundant with output_ts_offset, noone awnsered that really but then
an effort to deprecate initial_offset from segment was started and now
an effort to make output_ts_offset work in place of initial_offset

this seems the wrong order, first the question if the options
are redundant should have been awnsered then if they are they should
be tested and if they both work one could be deprecated

if output_ts_offset does not work as initial_offset replacement then
initial_offset should not have been deprecated yet

So lets start from scratch, what do the 2 options do ?
are they really the same ?

initial_offset adds a offset to the timestamps stored by the "sub
muxers" (maybe mpegts as used by segment or hls)
output_ts_offset as set by the user adds a offset to the timestamps
given to the main muxer (segment or hls here)

thats not the same

does it make sense to replace initial_offset by output_ts_offset?
or should 2 options be kept and amans original patch for hlsenc be
reconsidered ?

initial_offset was added as a fix for
https://trac.ffmpeg.org/ticket/2224
by stefano
is output_ts_offset solving this ticket ?
and is it the optimal solution ?

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I do not agree with what you have to say, but I'll defend to the death your
right to say it. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160911/8db4a41a/attachment.sig>


More information about the ffmpeg-devel mailing list