diff options
author | Dai, Jianhui J <jianhui.j.dai-at-intel.com@ffmpeg.org> | 2023-07-03 04:25:38 +0000 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2023-07-09 16:56:58 -0400 |
commit | 3b358f151ddc7543f1c0fc0cff82b6fe4ddf9cbf (patch) | |
tree | 066f0607a35136547133085b080e8708c28a9b1d /libavformat | |
parent | fcbee7efdfb55a25d573669114b5a968a72deb9f (diff) | |
download | ffmpeg-3b358f151ddc7543f1c0fc0cff82b6fe4ddf9cbf.tar.gz |
avformat/ivfenc: Set the "number of frames" in IVF header
Should set "number of frames" to bytes 24-27 of IVF header, not
duration.
It is described by [1], and confirmed by parsing all IVF files in [2].
This commit also updates the md5sum of refs to pass fate-cbs.
[1] Duck IVF - MultimediaWiki
https://wiki.multimedia.cx/index.php/Duck_IVF
[2] webm/vp8-test-vectors
https://chromium.googlesource.com/webm/vp8-test-vectors
Signed-off-by: Jianhui Dai <jianhui.j.dai@intel.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/ivfdec.c | 13 | ||||
-rw-r--r-- | libavformat/ivfenc.c | 13 |
2 files changed, 15 insertions, 11 deletions
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c index 511f2387ed..141ce4f1be 100644 --- a/libavformat/ivfdec.c +++ b/libavformat/ivfdec.c @@ -51,11 +51,18 @@ static int read_header(AVFormatContext *s) st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codecpar->codec_tag); st->codecpar->width = avio_rl16(s->pb); st->codecpar->height = avio_rl16(s->pb); - time_base.den = avio_rl32(s->pb); - time_base.num = avio_rl32(s->pb); - st->duration = avio_rl32(s->pb); + time_base.den = avio_rl32(s->pb); + time_base.num = avio_rl32(s->pb); + st->nb_frames = avio_rl32(s->pb); avio_skip(s->pb, 4); // unused + // Infer duration from nb_frames, in order to be backward compatible with + // previous IVF demuxer. + // It is popular to configure time_base to 1/frame_rate by IVF muxer, that + // the duration happens to be the same with nb_frames. See + // `https://chromium.googlesource.com/webm/vp8-test-vectors/+/refs/heads/main` + st->duration = st->nb_frames; + ffstream(st)->need_parsing = AVSTREAM_PARSE_HEADERS; if (!time_base.den || !time_base.num) { diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c index 47b4efbcd1..88399099d4 100644 --- a/libavformat/ivfenc.c +++ b/libavformat/ivfenc.c @@ -72,7 +72,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); // length is overwritten at the end of muxing + avio_wl32(pb, 0xFFFFFFFF); // "number of frames" is overwritten at the end of muxing + avio_wl32(pb, 0); // unused return 0; } @@ -99,16 +100,12 @@ static int ivf_write_trailer(AVFormatContext *s) AVIOContext *pb = s->pb; IVFEncContext *ctx = s->priv_data; - if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && - (ctx->frame_cnt > 1 || (ctx->frame_cnt == 1 && ctx->last_pkt_duration))) { + // overwrite the "number of frames" + if ((pb->seekable & AVIO_SEEKABLE_NORMAL)) { int64_t end = avio_tell(pb); avio_seek(pb, 24, SEEK_SET); - // overwrite the "length" field (duration) - avio_wl32(pb, ctx->last_pkt_duration ? - ctx->sum_delta_pts + ctx->last_pkt_duration : - ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1)); - avio_wl32(pb, 0); // zero out unused bytes + avio_wl32(pb, ctx->frame_cnt); avio_seek(pb, end, SEEK_SET); } |