Message ID | 4efe528fe8a1c2221bd4f1e81ce5de80b866589e.camel@kepstin.ca |
---|---|
State | New |
Headers | show |
On 01-10-2019 11:26 PM, Calvin Walton wrote: > The ffmpeg code read and wrote a 64bit duration field (in timebase units) in the ivf > header, where the libvpx and chromium code instead use a 32bit frame count field, and > then 32bits of unused (reserved?) space. > > Switch ffmpeg to match the behaviour of libvpx & chromium. > > Note that libvpx writes 0 to the frame count field when initially writing the header > then seeks back and overwrites it with the real frame count. ffmpeg used to write > 0xFFFFFFFF - I've changed the behaviour to match libvpx. > > References: > https://github.com/webmproject/libvpx/blob/v1.8.1/ivfenc.c#L16 > Which is called from: > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1191 (initial header) > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1209 (rewrite with frame count) > And the chromium parser: > https://chromium.googlesource.com/chromium/src/media/+/1681b9abff73fe0e3d0932aefdab4f039a284d1a/filters/ivf_parser.h > --- > libavformat/ivfdec.c | 3 ++- > libavformat/ivfenc.c | 11 ++++------- > 2 files changed, 6 insertions(+), 8 deletions(-) > > diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c > index 40ae464b76..2eaa5164ff 100644 > --- a/libavformat/ivfdec.c > +++ b/libavformat/ivfdec.c > @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) > st->codecpar->height = avio_rl16(s->pb); > time_base.den = avio_rl32(s->pb); > time_base.num = avio_rl32(s->pb); > - st->duration = avio_rl64(s->pb); > + st->nb_frames = avio_rl32(s->pb); > + avio_skip(s->pb, 4); // 32 bits unused > > st->need_parsing = AVSTREAM_PARSE_HEADERS; > > diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c > index adf72117e9..85ca6045ba 100644 > --- a/libavformat/ivfenc.c > +++ b/libavformat/ivfenc.c > @@ -22,8 +22,7 @@ > #include "libavutil/intreadwrite.h" > > typedef struct IVFEncContext { > - unsigned frame_cnt; > - uint64_t last_pts, sum_delta_pts; > + uint32_t frame_cnt; > } IVFEncContext; > > static int ivf_write_header(AVFormatContext *s) > @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) > avio_wl16(pb, par->height); > avio_wl32(pb, s->streams[0]->time_base.den); > avio_wl32(pb, s->streams[0]->time_base.num); > - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); > + avio_wl32(pb, 0); // frame count > + avio_wl32(pb, 0); // unused > > return 0; > } > @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) > avio_wl32(pb, pkt->size); > avio_wl64(pb, pkt->pts); > avio_write(pb, pkt->data, pkt->size); > - if (ctx->frame_cnt) > - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; > ctx->frame_cnt++; > - ctx->last_pts = pkt->pts; > > return 0; > } > @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) > size_t end = avio_tell(pb); > > avio_seek(pb, 24, SEEK_SET); > - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); > + avio_wl32(pb, ctx->frame_cnt); > avio_seek(pb, end, SEEK_SET); > } See http://www.ffmpeg.org/pipermail/ffmpeg-devel/2019-October/250871.html Gyan
On 10/1/2019 3:11 PM, Gyan wrote: > > > On 01-10-2019 11:26 PM, Calvin Walton wrote: >> The ffmpeg code read and wrote a 64bit duration field (in timebase >> units) in the ivf >> header, where the libvpx and chromium code instead use a 32bit frame >> count field, and >> then 32bits of unused (reserved?) space. >> >> Switch ffmpeg to match the behaviour of libvpx & chromium. >> >> Note that libvpx writes 0 to the frame count field when initially >> writing the header >> then seeks back and overwrites it with the real frame count. ffmpeg >> used to write >> 0xFFFFFFFF - I've changed the behaviour to match libvpx. >> >> References: >> https://github.com/webmproject/libvpx/blob/v1.8.1/ivfenc.c#L16 >> Which is called from: >> https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1191 >> (initial header) >> https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1209 >> (rewrite with frame count) >> And the chromium parser: >> https://chromium.googlesource.com/chromium/src/media/+/1681b9abff73fe0e3d0932aefdab4f039a284d1a/filters/ivf_parser.h >> >> --- >> libavformat/ivfdec.c | 3 ++- >> libavformat/ivfenc.c | 11 ++++------- >> 2 files changed, 6 insertions(+), 8 deletions(-) >> >> diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c >> index 40ae464b76..2eaa5164ff 100644 >> --- a/libavformat/ivfdec.c >> +++ b/libavformat/ivfdec.c >> @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) >> st->codecpar->height = avio_rl16(s->pb); >> time_base.den = avio_rl32(s->pb); >> time_base.num = avio_rl32(s->pb); >> - st->duration = avio_rl64(s->pb); >> + st->nb_frames = avio_rl32(s->pb); >> + avio_skip(s->pb, 4); // 32 bits unused >> st->need_parsing = AVSTREAM_PARSE_HEADERS; >> diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c >> index adf72117e9..85ca6045ba 100644 >> --- a/libavformat/ivfenc.c >> +++ b/libavformat/ivfenc.c >> @@ -22,8 +22,7 @@ >> #include "libavutil/intreadwrite.h" >> typedef struct IVFEncContext { >> - unsigned frame_cnt; >> - uint64_t last_pts, sum_delta_pts; >> + uint32_t frame_cnt; >> } IVFEncContext; >> static int ivf_write_header(AVFormatContext *s) >> @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) >> avio_wl16(pb, par->height); >> avio_wl32(pb, s->streams[0]->time_base.den); >> avio_wl32(pb, s->streams[0]->time_base.num); >> - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); >> + avio_wl32(pb, 0); // frame count >> + avio_wl32(pb, 0); // unused >> return 0; >> } >> @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, >> AVPacket *pkt) >> avio_wl32(pb, pkt->size); >> avio_wl64(pb, pkt->pts); >> avio_write(pb, pkt->data, pkt->size); >> - if (ctx->frame_cnt) >> - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; >> ctx->frame_cnt++; >> - ctx->last_pts = pkt->pts; >> return 0; >> } >> @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) >> size_t end = avio_tell(pb); >> avio_seek(pb, 24, SEEK_SET); >> - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / >> (ctx->frame_cnt - 1)); >> + avio_wl32(pb, ctx->frame_cnt); >> avio_seek(pb, end, SEEK_SET); >> } > > See http://www.ffmpeg.org/pipermail/ffmpeg-devel/2019-October/250871.html > > Gyan That patch was already NAKed, and a fixed version sent in replacement.
On 10/1/2019 2:56 PM, Calvin Walton wrote: > The ffmpeg code read and wrote a 64bit duration field (in timebase units) in the ivf > header, where the libvpx and chromium code instead use a 32bit frame count field, and > then 32bits of unused (reserved?) space. > > Switch ffmpeg to match the behaviour of libvpx & chromium. > > Note that libvpx writes 0 to the frame count field when initially writing the header > then seeks back and overwrites it with the real frame count. ffmpeg used to write > 0xFFFFFFFF - I've changed the behaviour to match libvpx. > > References: > https://github.com/webmproject/libvpx/blob/v1.8.1/ivfenc.c#L16 > Which is called from: > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1191 (initial header) > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1209 (rewrite with frame count) > And the chromium parser: > https://chromium.googlesource.com/chromium/src/media/+/1681b9abff73fe0e3d0932aefdab4f039a284d1a/filters/ivf_parser.h > --- > libavformat/ivfdec.c | 3 ++- > libavformat/ivfenc.c | 11 ++++------- > 2 files changed, 6 insertions(+), 8 deletions(-) > > diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c > index 40ae464b76..2eaa5164ff 100644 > --- a/libavformat/ivfdec.c > +++ b/libavformat/ivfdec.c > @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) > st->codecpar->height = avio_rl16(s->pb); > time_base.den = avio_rl32(s->pb); > time_base.num = avio_rl32(s->pb); > - st->duration = avio_rl64(s->pb); > + st->nb_frames = avio_rl32(s->pb); The demuxer will report N/A as duration after this. > + avio_skip(s->pb, 4); // 32 bits unused > > st->need_parsing = AVSTREAM_PARSE_HEADERS; > > diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c > index adf72117e9..85ca6045ba 100644 > --- a/libavformat/ivfenc.c > +++ b/libavformat/ivfenc.c > @@ -22,8 +22,7 @@ > #include "libavutil/intreadwrite.h" > > typedef struct IVFEncContext { > - unsigned frame_cnt; > - uint64_t last_pts, sum_delta_pts; > + uint32_t frame_cnt; > } IVFEncContext; > > static int ivf_write_header(AVFormatContext *s) > @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) > avio_wl16(pb, par->height); > avio_wl32(pb, s->streams[0]->time_base.den); > avio_wl32(pb, s->streams[0]->time_base.num); > - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); > + avio_wl32(pb, 0); // frame count > + avio_wl32(pb, 0); // unused > > return 0; > } > @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) > avio_wl32(pb, pkt->size); > avio_wl64(pb, pkt->pts); > avio_write(pb, pkt->data, pkt->size); > - if (ctx->frame_cnt) > - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; > ctx->frame_cnt++; > - ctx->last_pts = pkt->pts; > > return 0; > } > @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) > size_t end = avio_tell(pb); > > avio_seek(pb, 24, SEEK_SET); > - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); > + avio_wl32(pb, ctx->frame_cnt); > avio_seek(pb, end, SEEK_SET); > } Similarly, old versions of the ivf demuxer will read bogus duration values after this change.
On 01-10-2019 11:53 PM, James Almer wrote: > On 10/1/2019 3:11 PM, Gyan wrote: >> >> On 01-10-2019 11:26 PM, Calvin Walton wrote: >>> The ffmpeg code read and wrote a 64bit duration field (in timebase >>> units) in the ivf >>> header, where the libvpx and chromium code instead use a 32bit frame >>> count field, and >>> then 32bits of unused (reserved?) space. >>> >>> Switch ffmpeg to match the behaviour of libvpx & chromium. >>> >>> Note that libvpx writes 0 to the frame count field when initially >>> writing the header >>> then seeks back and overwrites it with the real frame count. ffmpeg >>> used to write >>> 0xFFFFFFFF - I've changed the behaviour to match libvpx. >>> >>> References: >>> https://github.com/webmproject/libvpx/blob/v1.8.1/ivfenc.c#L16 >>> Which is called from: >>> https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1191 >>> (initial header) >>> https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1209 >>> (rewrite with frame count) >>> And the chromium parser: >>> https://chromium.googlesource.com/chromium/src/media/+/1681b9abff73fe0e3d0932aefdab4f039a284d1a/filters/ivf_parser.h >>> >>> --- >>> libavformat/ivfdec.c | 3 ++- >>> libavformat/ivfenc.c | 11 ++++------- >>> 2 files changed, 6 insertions(+), 8 deletions(-) >>> >>> diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c >>> index 40ae464b76..2eaa5164ff 100644 >>> --- a/libavformat/ivfdec.c >>> +++ b/libavformat/ivfdec.c >>> @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) >>> st->codecpar->height = avio_rl16(s->pb); >>> time_base.den = avio_rl32(s->pb); >>> time_base.num = avio_rl32(s->pb); >>> - st->duration = avio_rl64(s->pb); >>> + st->nb_frames = avio_rl32(s->pb); >>> + avio_skip(s->pb, 4); // 32 bits unused >>> st->need_parsing = AVSTREAM_PARSE_HEADERS; >>> diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c >>> index adf72117e9..85ca6045ba 100644 >>> --- a/libavformat/ivfenc.c >>> +++ b/libavformat/ivfenc.c >>> @@ -22,8 +22,7 @@ >>> #include "libavutil/intreadwrite.h" >>> typedef struct IVFEncContext { >>> - unsigned frame_cnt; >>> - uint64_t last_pts, sum_delta_pts; >>> + uint32_t frame_cnt; >>> } IVFEncContext; >>> static int ivf_write_header(AVFormatContext *s) >>> @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) >>> avio_wl16(pb, par->height); >>> avio_wl32(pb, s->streams[0]->time_base.den); >>> avio_wl32(pb, s->streams[0]->time_base.num); >>> - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); >>> + avio_wl32(pb, 0); // frame count >>> + avio_wl32(pb, 0); // unused >>> return 0; >>> } >>> @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, >>> AVPacket *pkt) >>> avio_wl32(pb, pkt->size); >>> avio_wl64(pb, pkt->pts); >>> avio_write(pb, pkt->data, pkt->size); >>> - if (ctx->frame_cnt) >>> - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; >>> ctx->frame_cnt++; >>> - ctx->last_pts = pkt->pts; >>> return 0; >>> } >>> @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) >>> size_t end = avio_tell(pb); >>> avio_seek(pb, 24, SEEK_SET); >>> - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / >>> (ctx->frame_cnt - 1)); >>> + avio_wl32(pb, ctx->frame_cnt); >>> avio_seek(pb, end, SEEK_SET); >>> } >> See http://www.ffmpeg.org/pipermail/ffmpeg-devel/2019-October/250871.html >> >> Gyan > That patch was already NAKed, and a fixed version sent in replacement. I intended to link to the start of the thread, not the patch. Gyan
This is a superset of my patch(es). It should match the behavior of libvpx more closely, but the validity of the change from duration to number of frames depends on your interpretation of the reference implementation, which comments the field as "length". On Tue, 2019-10-01 at 23:41 +0530, Gyan wrote: > > On 01-10-2019 11:26 PM, Calvin Walton wrote: > > The ffmpeg code read and wrote a 64bit duration field (in timebase > > units) in the ivf > > header, where the libvpx and chromium code instead use a 32bit > > frame count field, and > > then 32bits of unused (reserved?) space. > > > > Switch ffmpeg to match the behaviour of libvpx & chromium. > > > > Note that libvpx writes 0 to the frame count field when initially > > writing the header > > then seeks back and overwrites it with the real frame count. ffmpeg > > used to write > > 0xFFFFFFFF - I've changed the behaviour to match libvpx. > > > > References: > > https://github.com/webmproject/libvpx/blob/v1.8.1/ivfenc.c#L16 > > Which is called from: > > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1191 > > (initial header) > > https://github.com/webmproject/libvpx/blob/v1.8.1/vpxenc.c#L1209 > > (rewrite with frame count) > > And the chromium parser: > > https://chromium.googlesource.com/chromium/src/media/+/1681b9abff73fe0e3d0932aefdab4f039a284d1a/filters/ivf_parser.h > > --- > > libavformat/ivfdec.c | 3 ++- > > libavformat/ivfenc.c | 11 ++++------- > > 2 files changed, 6 insertions(+), 8 deletions(-) > > > > diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c > > index 40ae464b76..2eaa5164ff 100644 > > --- a/libavformat/ivfdec.c > > +++ b/libavformat/ivfdec.c > > @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) > > st->codecpar->height = avio_rl16(s->pb); > > time_base.den = avio_rl32(s->pb); > > time_base.num = avio_rl32(s->pb); > > - st->duration = avio_rl64(s->pb); > > + st->nb_frames = avio_rl32(s->pb); > > + avio_skip(s->pb, 4); // 32 bits unused > > > > st->need_parsing = AVSTREAM_PARSE_HEADERS; > > > > diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c > > index adf72117e9..85ca6045ba 100644 > > --- a/libavformat/ivfenc.c > > +++ b/libavformat/ivfenc.c > > @@ -22,8 +22,7 @@ > > #include "libavutil/intreadwrite.h" > > > > typedef struct IVFEncContext { > > - unsigned frame_cnt; > > - uint64_t last_pts, sum_delta_pts; > > + uint32_t frame_cnt; > > } IVFEncContext; > > > > static int ivf_write_header(AVFormatContext *s) > > @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) > > avio_wl16(pb, par->height); > > avio_wl32(pb, s->streams[0]->time_base.den); > > avio_wl32(pb, s->streams[0]->time_base.num); > > - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); > > + avio_wl32(pb, 0); // frame count > > + avio_wl32(pb, 0); // unused > > > > return 0; > > } > > @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, > > AVPacket *pkt) > > avio_wl32(pb, pkt->size); > > avio_wl64(pb, pkt->pts); > > avio_write(pb, pkt->data, pkt->size); > > - if (ctx->frame_cnt) > > - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; > > ctx->frame_cnt++; > > - ctx->last_pts = pkt->pts; > > > > return 0; > > } > > @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) > > size_t end = avio_tell(pb); > > > > avio_seek(pb, 24, SEEK_SET); > > - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx- > > >frame_cnt - 1)); > > + avio_wl32(pb, ctx->frame_cnt); > > avio_seek(pb, end, SEEK_SET); > > } > > See > http://www.ffmpeg.org/pipermail/ffmpeg-devel/2019-October/250871.html > > 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".
On Tue, 2019-10-01 at 15:26 -0300, James Almer wrote: > On 10/1/2019 2:56 PM, Calvin Walton wrote: > > libavformat/ivfdec.c | 3 ++- > > libavformat/ivfenc.c | 11 ++++------- > > 2 files changed, 6 insertions(+), 8 deletions(-) > > > > diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c > > index 40ae464b76..2eaa5164ff 100644 > > --- a/libavformat/ivfdec.c > > +++ b/libavformat/ivfdec.c > > @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) > > st->codecpar->height = avio_rl16(s->pb); > > time_base.den = avio_rl32(s->pb); > > time_base.num = avio_rl32(s->pb); > > - st->duration = avio_rl64(s->pb); > > + st->nb_frames = avio_rl32(s->pb); > > The demuxer will report N/A as duration after this. This is intentional, as the container format doesn't have a duration field, only a frame count. I suppose it might be possible to estimate a duration by probing the file to guess the average framerate, and then dividing the frame count by the framerate - but I'm not familiar with how that could be done in the demuxer > > size_t end = avio_tell(pb); > > > > avio_seek(pb, 24, SEEK_SET); > > - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx- > > >frame_cnt - 1)); > > + avio_wl32(pb, ctx->frame_cnt); > > avio_seek(pb, end, SEEK_SET); > > } > > Similarly, old versions of the ivf demuxer will read bogus duration > values after this change. Old versions of the ivf demuxer read bogus duration values for files generated by vpxenc in the case where the timebase is something other than 1/framerate (i think this can happen if a timebase is manually set or if a fractional framerate is used) or if the file is vfr (I'm not sure if vpxenc can generate vfr files).
On Tue, 2019-10-01 at 13:56 -0400, Calvin Walton wrote: > The ffmpeg code read and wrote a 64bit duration field (in timebase > units) in the ivf > header, where the libvpx and chromium code instead use a 32bit frame > count field, and > then 32bits of unused (reserved?) space. > > Switch ffmpeg to match the behaviour of libvpx & chromium. Just to note (now that I've got fate working on my dev machine again), if this patch is applied, a bunch of the test references will need updates due to the ivf file output changing. I'll include those updates if I do a second patch revision.
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c index 40ae464b76..2eaa5164ff 100644 --- a/libavformat/ivfdec.c +++ b/libavformat/ivfdec.c @@ -53,7 +53,8 @@ static int read_header(AVFormatContext *s) st->codecpar->height = avio_rl16(s->pb); time_base.den = avio_rl32(s->pb); time_base.num = avio_rl32(s->pb); - st->duration = avio_rl64(s->pb); + st->nb_frames = avio_rl32(s->pb); + avio_skip(s->pb, 4); // 32 bits unused st->need_parsing = AVSTREAM_PARSE_HEADERS; diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c index adf72117e9..85ca6045ba 100644 --- a/libavformat/ivfenc.c +++ b/libavformat/ivfenc.c @@ -22,8 +22,7 @@ #include "libavutil/intreadwrite.h" typedef struct IVFEncContext { - unsigned frame_cnt; - uint64_t last_pts, sum_delta_pts; + uint32_t frame_cnt; } IVFEncContext; static int ivf_write_header(AVFormatContext *s) @@ -53,7 +52,8 @@ static int ivf_write_header(AVFormatContext *s) avio_wl16(pb, par->height); avio_wl32(pb, s->streams[0]->time_base.den); avio_wl32(pb, s->streams[0]->time_base.num); - avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); + avio_wl32(pb, 0); // frame count + avio_wl32(pb, 0); // unused return 0; } @@ -66,10 +66,7 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) avio_wl32(pb, pkt->size); avio_wl64(pb, pkt->pts); avio_write(pb, pkt->data, pkt->size); - if (ctx->frame_cnt) - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; ctx->frame_cnt++; - ctx->last_pts = pkt->pts; return 0; } @@ -83,7 +80,7 @@ static int ivf_write_trailer(AVFormatContext *s) size_t end = avio_tell(pb); avio_seek(pb, 24, SEEK_SET); - avio_wl64(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); + avio_wl32(pb, ctx->frame_cnt); avio_seek(pb, end, SEEK_SET); }