Message ID | 20210318011727.517496-1-jerome@percipient.ai |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] added parameter to dash encoder for start available time | expand |
Context | Check | Description |
---|---|---|
andriy/configure | warning | Failed to apply patch |
On Thu, Mar 18, 2021 at 3:49 AM Jerome Berclaz <jerome@percipient.ai> wrote: > > --- > libavformat/dashenc.c | 28 ++++++++++++++++++++-------- > 1 file changed, 20 insertions(+), 8 deletions(-) So right now we do have an option in ffmpeg.c called itsoffset. It lets you configure the input offset in time (seconds - such as "1337.123" or time format - such as "00:00:01.123"). The only problem with it right now is that unless you set -copyts it will not get applied for anything else than subtitles, as the offset gets applied before and is not taken into account in the "start from PTS 0" calculation for video/audio streams. I have been meaning to do some git blaming and asking the people still around who added that logic, if that was really meant - since as far as I can tell even people such as Martin actually recommended me this option - probably expecting for it to work. If we just make itsoffset usable without copyts (just take it into mention in the zero'ification process), I think all these options in the output modules would effectively become unnecessary, since your DTS/PTS will start from nonzero positive value depending on the itsoffset. Best regards, Jan
On 2021-03-18 20:12, Jan Ekström wrote: > So right now we do have an option in ffmpeg.c called itsoffset. It > lets you configure the input offset in time (seconds - such as > "1337.123" or time format - such as "00:00:01.123"). The only problem > with it right now is that unless you set -copyts it will not get > applied for anything else than subtitles, as the offset gets applied > before and is not taken into account in the "start from PTS 0" > calculation for video/audio streams. Not the case. ffmpeg -f lavfi -itsoffset 3 -i nullsrc=r=1:d=3 -vf showinfo -f null - gives [Parsed_showinfo_0 @ 0000019cc1b88540] n: 0 pts: 3 pts_time:3 ... [Parsed_showinfo_0 @ 0000019cc1b88540] n: 1 pts: 4 pts_time:4 ... [Parsed_showinfo_0 @ 0000019cc1b88540] n: 2 pts: 5 pts_time:5 ... I've used it many times to adjust sync among streams. Regards, Gyan
On Thu, Mar 18, 2021, 17:01 Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > On 2021-03-18 20:12, Jan Ekström wrote: > > So right now we do have an option in ffmpeg.c called itsoffset. It > > lets you configure the input offset in time (seconds - such as > > "1337.123" or time format - such as "00:00:01.123"). The only problem > > with it right now is that unless you set -copyts it will not get > > applied for anything else than subtitles, as the offset gets applied > > before and is not taken into account in the "start from PTS 0" > > calculation for video/audio streams. > > Not the case. > > ffmpeg -f lavfi -itsoffset 3 -i nullsrc=r=1:d=3 -vf showinfo -f null - > > gives > > [Parsed_showinfo_0 @ 0000019cc1b88540] n: 0 pts: 3 pts_time:3 ... > [Parsed_showinfo_0 @ 0000019cc1b88540] n: 1 pts: 4 pts_time:4 ... > [Parsed_showinfo_0 @ 0000019cc1b88540] n: 2 pts: 5 pts_time:5 ... > > I've used it many times to adjust sync among streams. > > Regards, > Gyan > Very interesting! I will have to retest, I just recall that the last time I tried it got applied when there were multiple streams in an input when the start_time based adjustment was done. Jan >
On Thu, Mar 18, 2021 at 5:07 PM Jan Ekström <jeebjp@gmail.com> wrote: > > On Thu, Mar 18, 2021, 17:01 Gyan Doshi <ffmpeg@gyani.pro> wrote: >> >> >> >> On 2021-03-18 20:12, Jan Ekström wrote: >> > So right now we do have an option in ffmpeg.c called itsoffset. It >> > lets you configure the input offset in time (seconds - such as >> > "1337.123" or time format - such as "00:00:01.123"). The only problem >> > with it right now is that unless you set -copyts it will not get >> > applied for anything else than subtitles, as the offset gets applied >> > before and is not taken into account in the "start from PTS 0" >> > calculation for video/audio streams. >> >> Not the case. >> >> ffmpeg -f lavfi -itsoffset 3 -i nullsrc=r=1:d=3 -vf showinfo -f null - >> >> gives >> >> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 0 pts: 3 pts_time:3 ... >> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 1 pts: 4 pts_time:4 ... >> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 2 pts: 5 pts_time:5 ... >> >> I've used it many times to adjust sync among streams. >> >> Regards, >> Gyan > > > Very interesting! > > I will have to retest, I just recall that the last time I tried it got applied when there were multiple streams in an input when the start_time based adjustment was done. Right, so taking in a Matroska file it works fine, but when taking in an MPEG-TS file with a start_time it not only transforms (start_time + input_ts_offset) to (input_ts_offset), but just to 0 :) . Example: ffmpeg -v verbose -debug_ts -itsoffset "1616090389" -i 'https://megumin.fushizen.eu/samples/switchingaudio.ts' -c copy -bsf:a aac_adtstoasc -movflags dash+frag_discont+delay_moov -vframes 5 -f mp4 - > test.mp4 Probed start_time: Duration: 00:00:15.25, start: 19516.478644, bitrate: 23823 kb/s And how ffmpeg.c then adjusted it: demuxer -> ist_index:2 type:audio next_dts:NOPTS next_dts_time:NOPTS next_pts:NOPTS next_pts_time:NOPTS pkt_pts:1756483078 pkt_pts_time:19516.5 pkt_dts:1756483078 pkt_dts_time:19516.5 off:1616070872521356 off_time:1.61607e+09 demuxer+ffmpeg -> ist_index:2 type:audio pkt_pts:0 pkt_pts_time:0 pkt_dts:0 pkt_dts_time:0 off:-19516478644 off_time:-19516.5 Thus, ffmpeg.c is not only adjusting the timestamp to start at zero with the start_time, but also takes the itsoffset off as well. Best regards, Jan
On 2021-03-19 03:22, Jan Ekström wrote: > On Thu, Mar 18, 2021 at 5:07 PM Jan Ekström <jeebjp@gmail.com> wrote: >> On Thu, Mar 18, 2021, 17:01 Gyan Doshi <ffmpeg@gyani.pro> wrote: >>> >>> >>> On 2021-03-18 20:12, Jan Ekström wrote: >>>> So right now we do have an option in ffmpeg.c called itsoffset. It >>>> lets you configure the input offset in time (seconds - such as >>>> "1337.123" or time format - such as "00:00:01.123"). The only problem >>>> with it right now is that unless you set -copyts it will not get >>>> applied for anything else than subtitles, as the offset gets applied >>>> before and is not taken into account in the "start from PTS 0" >>>> calculation for video/audio streams. >>> Not the case. >>> >>> ffmpeg -f lavfi -itsoffset 3 -i nullsrc=r=1:d=3 -vf showinfo -f null - >>> >>> gives >>> >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 0 pts: 3 pts_time:3 ... >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 1 pts: 4 pts_time:4 ... >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 2 pts: 5 pts_time:5 ... >>> >>> I've used it many times to adjust sync among streams. >>> >>> Regards, >>> Gyan >> >> Very interesting! >> >> I will have to retest, I just recall that the last time I tried it got applied when there were multiple streams in an input when the start_time based adjustment was done. > Right, so taking in a Matroska file it works fine, but when taking in > an MPEG-TS file with a start_time it not only transforms (start_time + > input_ts_offset) to (input_ts_offset), but just to 0 :) . > > Example: > ffmpeg -v verbose -debug_ts -itsoffset "1616090389" -i > 'https://megumin.fushizen.eu/samples/switchingaudio.ts' -c copy -bsf:a > aac_adtstoasc -movflags dash+frag_discont+delay_moov -vframes 5 -f mp4 > - > test.mp4 > > Probed start_time: > Duration: 00:00:15.25, start: 19516.478644, bitrate: 23823 kb/s > > And how ffmpeg.c then adjusted it: > demuxer -> ist_index:2 type:audio next_dts:NOPTS next_dts_time:NOPTS > next_pts:NOPTS next_pts_time:NOPTS pkt_pts:1756483078 > pkt_pts_time:19516.5 pkt_dts:1756483078 pkt_dts_time:19516.5 > off:1616070872521356 off_time:1.61607e+09 > demuxer+ffmpeg -> ist_index:2 type:audio pkt_pts:0 pkt_pts_time:0 > pkt_dts:0 pkt_dts_time:0 off:-19516478644 off_time:-19516.5 > > Thus, ffmpeg.c is not only adjusting the timestamp to start at zero > with the start_time, but also takes the itsoffset off as well. This affects formats with AVFMT_TS_DISCONT flag, ffmpeg checks for a discontinuity and readjusts the file offset to make output timestamps smooth. Add -dts_delta_threshold 1616090389 alongside itsoffset to prevent this readjustment. Perhaps, both the itsoffset and ts_scale adjustments should be moved to after the discontinuity checks. Regards, Gyan
Hi all, Thanks for the comments on my patch. I should have given more explanations, but this is my first time using git-send-email and I wasn't able to add text to the patch. The reason for the patch occurred while trying to live stream a Dash feed with low latency. I did not use a timeline, hence having a precise start time is crucial, otherwise the player will try to download chunks at the wrong time. In the current implementation (branch 4.2) the start time is set to the system time, which may not correspond exactly to the live feed start time. This new parameter allows the user to pass the exact value for the start time. I've seen that the dash encoder has been refactored in branch 4.3, so I don't know if this change is relevant anymore. The patch was intended for branch 4.2. Thanks, Jerome On Thu, Mar 18, 2021 at 9:20 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > On 2021-03-19 03:22, Jan Ekström wrote: > > On Thu, Mar 18, 2021 at 5:07 PM Jan Ekström <jeebjp@gmail.com> wrote: > >> On Thu, Mar 18, 2021, 17:01 Gyan Doshi <ffmpeg@gyani.pro> wrote: > >>> > >>> > >>> On 2021-03-18 20:12, Jan Ekström wrote: > >>>> So right now we do have an option in ffmpeg.c called itsoffset. It > >>>> lets you configure the input offset in time (seconds - such as > >>>> "1337.123" or time format - such as "00:00:01.123"). The only problem > >>>> with it right now is that unless you set -copyts it will not get > >>>> applied for anything else than subtitles, as the offset gets applied > >>>> before and is not taken into account in the "start from PTS 0" > >>>> calculation for video/audio streams. > >>> Not the case. > >>> > >>> ffmpeg -f lavfi -itsoffset 3 -i nullsrc=r=1:d=3 -vf showinfo -f > null - > >>> > >>> gives > >>> > >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 0 pts: 3 pts_time:3 > ... > >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 1 pts: 4 pts_time:4 > ... > >>> [Parsed_showinfo_0 @ 0000019cc1b88540] n: 2 pts: 5 pts_time:5 > ... > >>> > >>> I've used it many times to adjust sync among streams. > >>> > >>> Regards, > >>> Gyan > >> > >> Very interesting! > >> > >> I will have to retest, I just recall that the last time I tried it got > applied when there were multiple streams in an input when the start_time > based adjustment was done. > > Right, so taking in a Matroska file it works fine, but when taking in > > an MPEG-TS file with a start_time it not only transforms (start_time + > > input_ts_offset) to (input_ts_offset), but just to 0 :) . > > > > Example: > > ffmpeg -v verbose -debug_ts -itsoffset "1616090389" -i > > 'https://megumin.fushizen.eu/samples/switchingaudio.ts' -c copy -bsf:a > > aac_adtstoasc -movflags dash+frag_discont+delay_moov -vframes 5 -f mp4 > > - > test.mp4 > > > > Probed start_time: > > Duration: 00:00:15.25, start: 19516.478644, bitrate: 23823 kb/s > > > > And how ffmpeg.c then adjusted it: > > demuxer -> ist_index:2 type:audio next_dts:NOPTS next_dts_time:NOPTS > > next_pts:NOPTS next_pts_time:NOPTS pkt_pts:1756483078 > > pkt_pts_time:19516.5 pkt_dts:1756483078 pkt_dts_time:19516.5 > > off:1616070872521356 off_time:1.61607e+09 > > demuxer+ffmpeg -> ist_index:2 type:audio pkt_pts:0 pkt_pts_time:0 > > pkt_dts:0 pkt_dts_time:0 off:-19516478644 off_time:-19516.5 > > > > Thus, ffmpeg.c is not only adjusting the timestamp to start at zero > > with the start_time, but also takes the itsoffset off as well. > > This affects formats with AVFMT_TS_DISCONT flag, ffmpeg checks for a > discontinuity and readjusts the file offset to make output timestamps > smooth. > > Add -dts_delta_threshold 1616090389 alongside itsoffset to prevent this > readjustment. Perhaps, both the itsoffset and ts_scale adjustments > should be moved to after the discontinuity checks. > > Regards, > Gyan > _______________________________________________ > 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".
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 24d43c34ea..81855ca8d0 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -149,6 +149,7 @@ typedef struct DASHContext { int master_publish_rate; int nr_of_streams_to_flush; int nr_of_streams_flushed; + int64_t start_time_ms; } DASHContext; static struct codec_string { @@ -725,13 +726,11 @@ static void write_time(AVIOContext *out, int64_t time) avio_printf(out, "%d.%dS", seconds, fractions / (AV_TIME_BASE / 10)); } -static void format_date_now(char *buf, int size) +static void format_date(uint64_t epoch_ms, char *buf, int size) { struct tm *ptm, tmbuf; - int64_t time_us = av_gettime(); - int64_t time_ms = time_us / 1000; - const time_t time_s = time_ms / 1000; - int millisec = time_ms - (time_s * 1000); + const time_t time_s = epoch_ms / 1000; + int millisec = epoch_ms - (time_s * 1000); ptm = gmtime_r(&time_s, &tmbuf); if (ptm) { int len; @@ -744,6 +743,12 @@ static void format_date_now(char *buf, int size) } } +static void format_date_now(char *buf, int size) +{ + int64_t time_us = av_gettime(); + format_date( time_us / 1000, buf, size); +} + static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_index, int final) { @@ -1712,10 +1717,16 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) os->last_pts = pkt->pts; if (!c->availability_start_time[0]) { - int64_t start_time_us = av_gettime(); - c->start_time_s = start_time_us / 1000000; - format_date_now(c->availability_start_time, + if (c->start_time_ms) { + c->start_time_s = c->start_time_ms / 1000; + format_date(c->start_time_ms, c->availability_start_time, sizeof(c->availability_start_time)); + } else { + int64_t start_time_us = av_gettime(); + c->start_time_s = start_time_us / 1000000; + format_date_now(c->availability_start_time, + sizeof(c->availability_start_time)); + } } if (!os->availability_time_offset && pkt->duration) { @@ -1922,6 +1933,7 @@ static const AVOption options[] = { { "ignore_io_errors", "Ignore IO errors during open and write. Useful for long-duration runs with network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "lhls", "Enable Low-latency HLS(Experimental). Adds #EXT-X-PREFETCH tag with current segment's URI", OFFSET(lhls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "master_m3u8_publish_rate", "Publish master playlist every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E}, + { "start_time_ms", "stream start time in epoch milliseconds", OFFSET(start_time_ms), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, UINT64_MAX, E, "ms"}, { NULL }, };