On Sun, Apr 21, 2019 at 5:51 PM Jun Li <junli1...@gmail.com> wrote: > Fix #7144. > The current packet duration calculation is heuristic, which uses the > historical durtion as current duration. This commit adds the option > to buffer one packet and calcuate its duration when next packet arrives. > Obviously it adds one frame latency, which might be significant for > VFR live content, so expose it as an option for user to choose. > --- > doc/muxers.texi | 4 ++++ > libavformat/dashenc.c | 44 +++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 46 insertions(+), 2 deletions(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index ee99ef621e..76954877a6 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -321,6 +321,10 @@ This is an experimental feature. > @item -master_m3u8_publish_rate @var{master_m3u8_publish_rate} > Publish master playlist repeatedly every after specified number of > segment intervals. > > +@item -skip_estimate_pkt_duration > +If this flag is set, packet duration will be calcuated as the diff of the > current and next packet timestamp. The option is not for constant frame rate > +content because heuristic estimation will be accurate in this case. > Default value is 0. > + > @end table > > @anchor{framecrc} > diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c > index 5f1333e436..f89d68a51b 100644 > --- a/libavformat/dashenc.c > +++ b/libavformat/dashenc.c > @@ -101,6 +101,7 @@ typedef struct OutputStream { > double availability_time_offset; > int total_pkt_size; > int muxer_overhead; > + AVPacket* prev_pkt; > } OutputStream; > > typedef struct DASHContext { > @@ -145,6 +146,7 @@ typedef struct DASHContext { > int ignore_io_errors; > int lhls; > int master_publish_rate; > + int skip_estiamte_pkt_duration; > int nr_of_streams_to_flush; > int nr_of_streams_flushed; > } DASHContext; > @@ -1559,7 +1561,7 @@ static int dash_flush(AVFormatContext *s, int final, > int stream) > } else { > snprintf(os->full_path, sizeof(os->full_path), "%s%s", > c->dirname, os->initfile); > } > - > + > ret = flush_dynbuf(c, os, &range_length); > if (ret < 0) > break; > @@ -1643,7 +1645,7 @@ static int dash_flush(AVFormatContext *s, int final, > int stream) > return ret; > } > > -static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) > +static int dash_write_packet_internal(AVFormatContext *s, AVPacket *pkt) > { > DASHContext *c = s->priv_data; > AVStream *st = s->streams[pkt->stream_index]; > @@ -1789,11 +1791,47 @@ static int dash_write_packet(AVFormatContext *s, > AVPacket *pkt) > return ret; > } > > +static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) > +{ > + DASHContext *c = s->priv_data; > + if (!c->skip_estiamte_pkt_duration) > + return dash_write_packet_internal(s, pkt); > + > + AVStream *st = s->streams[pkt->stream_index]; > + OutputStream *os = &c->streams[pkt->stream_index]; > + int ret = 0; > + > + if (os->prev_pkt) { > + if (!os->prev_pkt->duration && pkt->dts >= os->prev_pkt->dts) > + os->prev_pkt->duration = pkt->dts - os->prev_pkt->dts; > + ret = dash_write_packet_internal(s, os->prev_pkt); > + av_packet_unref(os->prev_pkt); > + if (av_packet_ref(os->prev_pkt, pkt)) { > + av_log(s, AV_LOG_ERROR, "Failed to set up a reference to > current packet, lost one packet for muxing.\n"); > + av_packet_free(&os->prev_pkt); > + } > + } else { > + os->prev_pkt = av_packet_clone(pkt); > + } > + return ret; > +} > + > static int dash_write_trailer(AVFormatContext *s) > { > DASHContext *c = s->priv_data; > int i; > > + if (c->skip_estiamte_pkt_duration) { > + for (i = 0; i < s->nb_streams; i++) { > + OutputStream *os = &c->streams[i]; > + if (os->prev_pkt) { > + // write last packet > + dash_write_packet_internal(s, os->prev_pkt); > + av_packet_free(&os->prev_pkt); > + } > + } > + } > + > if (s->nb_streams > 0) { > OutputStream *os = &c->streams[0]; > // If no segments have been written so far, try to do a crude > @@ -1888,6 +1926,8 @@ 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}, > + { "skip_estimate_pkt_duration", "Skip estimate packet duration, > buffer previous packet for calculating its duration.", > OFFSET(skip_estiamte_pkt_duration), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E > }, > + > { NULL }, > }; > > -- > 2.17.1
Ping. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".