[FFmpeg-devel] [PATCH 1/2] avformat/nutenc: fix duration estimation by writing EOR packets

Michael Niedermayer michael at niedermayer.cc
Thu Dec 20 02:16:51 EET 2018


On Wed, Dec 19, 2018 at 09:35:28PM +0100, Paul B Mahol wrote:
> On 12/19/18, Michael Niedermayer <michael at niedermayer.cc> wrote:
> > On Tue, Dec 18, 2018 at 10:55:16PM +0100, Paul B Mahol wrote:
> >> On 12/18/18, Michael Niedermayer <michael at niedermayer.cc> wrote:
> >> > On Tue, Dec 18, 2018 at 02:56:54PM +0100, Paul B Mahol wrote:
> >> >> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> >> >> ---
> >> >>  libavformat/nut.h    |   3 +
> >> >>  libavformat/nutenc.c | 130
> >> >> +++++++++++++++++++++++++++++++++++++++++--
> >> >>  2 files changed, 129 insertions(+), 4 deletions(-)
> >> >>
> >> >> diff --git a/libavformat/nut.h b/libavformat/nut.h
> >> >> index a4409ee23d..4b15dca1ea 100644
> >> >> --- a/libavformat/nut.h
> >> >> +++ b/libavformat/nut.h
> >> >> @@ -76,6 +76,9 @@ typedef struct StreamContext {
> >> >>      int last_flags;
> >> >>      int skip_until_key_frame;
> >> >>      int64_t last_pts;
> >> >> +    int64_t eor_pts;
> >> >> +    int64_t eor_dts;
> >> >> +    int eor_flushed;
> >> >>      int time_base_id;
> >> >>      AVRational *time_base;
> >> >>      int msb_pts_shift;
> >> >> diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
> >> >> index e9a3bb49db..9d1c540a9d 100644
> >> >> --- a/libavformat/nutenc.c
> >> >> +++ b/libavformat/nutenc.c
> >> >> @@ -940,6 +940,80 @@ fail:
> >> >>      return ret;
> >> >>  }
> >> >>
> >> >> +static void nut_update_max_pts(AVFormatContext *s, int stream_index,
> >> >> int64_t pts)
> >> >> +{
> >> >> +    NUTContext *nut = s->priv_data;
> >> >> +    StreamContext *nus = &nut->stream[stream_index];
> >> >> +
> >> >> +    if (!nut->max_pts_tb || av_compare_ts(nut->max_pts,
> >> >> *nut->max_pts_tb,
> >> >> pts, *nus->time_base) < 0) {
> >> >> +        nut->max_pts = pts;
> >> >> +        nut->max_pts_tb = nus->time_base;
> >> >> +    }
> >> >> +}
> >> >> +
> >> >> +static int nut_write_eor(AVFormatContext *s, AVPacket *pkt)
> >> >> +{
> >> >> +    AVIOContext *bc = s->pb, *dyn_bc;
> >> >> +    NUTContext *nut = s->priv_data;
> >> >> +    StreamContext *nus = &nut->stream[pkt->stream_index];
> >> >> +    int ret, frame_code, flags, needed_flags;
> >> >> +    int64_t pts = pkt->pts;
> >> >> +    int64_t coded_pts;
> >> >> +    FrameCode *fc;
> >> >> +
> >> >> +    coded_pts = pts & ((1 << nus->msb_pts_shift) - 1);
> >> >> +    if (ff_lsb2full(nus, coded_pts) != pts)
> >> >> +        coded_pts = pts + (1 << nus->msb_pts_shift);
> >> >> +
> >> >> +    nut->last_syncpoint_pos = avio_tell(bc);
> >> >> +    ret                     = avio_open_dyn_buf(&dyn_bc);
> >> >> +    if (ret < 0)
> >> >> +        return ret;
> >> >> +    put_tt(nut, nus->time_base, dyn_bc, pkt->dts);
> >> >> +    ff_put_v(dyn_bc, 0);
> >> >> +
> >> >> +    if (nut->flags & NUT_BROADCAST) {
> >> >> +        put_tt(nut, nus->time_base, dyn_bc,
> >> >> +               av_rescale_q(av_gettime(), AV_TIME_BASE_Q,
> >> >> *nus->time_base));
> >> >> +    }
> >> >> +    put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
> >> >> +
> >> >> +    frame_code  = -1;
> >> >> +    for (int i = 0; i < 256; i++) {
> >> >> +        FrameCode *fc = &nut->frame_code[i];
> >> >> +        int flags     = fc->flags;
> >> >> +
> >> >> +        if (flags & FLAG_INVALID)
> >> >> +            continue;
> >> >> +
> >> >> +        if (!(flags & FLAG_CODED)) {
> >> >> +            continue;
> >> >> +        }
> >> >> +
> >> >> +        frame_code = i;
> >> >> +        break;
> >> >> +    }
> >> >> +    av_assert0(frame_code != -1);
> >> >> +
> >> >> +    fc           = &nut->frame_code[frame_code];
> >> >> +    flags        = fc->flags;
> >> >> +    needed_flags = FLAG_KEY | FLAG_EOR | FLAG_CODED_PTS |
> >> >> FLAG_STREAM_ID;
> >> >> +
> >> >> +    ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
> >> >> +    avio_w8(bc, frame_code);
> >> >> +    if (flags & FLAG_CODED) {
> >> >> +        ff_put_v(bc, (flags ^ needed_flags) & ~(FLAG_CODED));
> >> >> +        flags = needed_flags;
> >> >> +    }
> >> >> +    if (flags & FLAG_STREAM_ID)  ff_put_v(bc, pkt->stream_index);
> >> >> +    if (flags & FLAG_CODED_PTS)  ff_put_v(bc, coded_pts);
> >> >> +    ffio_get_checksum(bc);
> >> >> +
> >> >> +    nut_update_max_pts(s, pkt->stream_index, pkt->pts);
> >> >> +
> >> >> +    return 0;
> >> >> +}
> >> >> +
> >> >>  static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
> >> >>  {
> >> >>      NUTContext *nut    = s->priv_data;
> >> >
> >> >> @@ -956,6 +1030,9 @@ static int nut_write_packet(AVFormatContext *s,
> >> >> AVPacket *pkt)
> >> >>      int data_size = pkt->size;
> >> >>      uint8_t *sm_buf = NULL;
> >> >>
> >> >> +    if (!data_size)
> >> >> +        return nut_write_eor(s, pkt);
> >> >
> >> > that could happen for non EOR packets too
> >>
> >> How would you solve it?
> >
> > the flags of the packet should be the easiest way to mark EOR packets
> >
> 
> By adding flag to libavformat ?

by using a bit in AVPacket.flags
The only potential change outside the demuxer would be to document that the
specific bit is used internally in demuxers



[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

it is not once nor twice but times without number that the same ideas make
their appearance in the world. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20181220/13898932/attachment.sig>


More information about the ffmpeg-devel mailing list