PR #25661 opened by florianmodel URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25661 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25661.patch
DV input is currently reported as 60000 fps, which breaks frame-count-based progress and ETA calculations in applications such as HandBrake. This fixes [FFmpeg ticket #11339](https://trac.ffmpeg.org/ticket/11339), reported by Dave Rice, and the upstream cause of [HandBrake #6635](https://github.com/HandBrake/HandBrake/issues/6635) / [#6474](https://github.com/HandBrake/HandBrake/issues/6474). Since c7a852b638b88f129790af31fc47c870c329eaaa, the DV stream time base is fixed at 1/60000. Inverting it to set avg_frame_rate therefore yields 60000/1 for every profile. Derive avg_frame_rate from the current DV profile time base instead, as already done for packet duration and bitrate. The fix also covers the shared demuxer used by Type 1 DV-in-AVI. Reproduce on the unmodified master: ```sh ./ffmpeg -y -f lavfi -i testsrc2=size=720x480:rate=30000/1001 -frames:v 3 -c:v dvvideo -pix_fmt yuv411p -chroma_sample_location topleft -f dv test.dv ./ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate,time_base test.dv ``` Before: avg_frame_rate=60000/1. After: avg_frame_rate=30000/1001. The stream time base remains 1/60000. Validation against master a88838af48 on macOS arm64: - Four new sample-free FATE tests cover PAL, NTSC, 720p50 and 720p60, checking average frame rate, stream time base, packet PTS and duration. All fail before the fix and pass after it. - `make -j8 fate`: 3078 tests passed. The separate FATE sample archive was not configured, so sample-dependent tests were not run. - Generated raw DV and Type 1 DV-in-AVI (video-only AVI with embedded DV audio, stream header changed from vids to iavs) both change from 60000/1 to 30000/1001. Every demuxed packet, including audio, compares identically before and after the fix. A Type 2 AVI control retains 30000/1001. - `git diff --check` passes. `tools/patcheck` was attempted but encounters BSD grep/xargs portability errors on macOS. Development and testing were performed with AI assistance (OpenAI Codex). >From 72fc2e960f37ff76e24df572553cf403975a7f01 Mon Sep 17 00:00:00 2001 From: florianmodel <[email protected]> Date: Sun, 1 Nov 2026 17:30:42 +0000 Subject: [PATCH] avformat/dv: derive average frame rate from the DV profile Since c7a852b638b88f129790af31fc47c870c329eaaa, the DV demuxer uses a fixed 1/60000 video time base. Inverting that time base therefore sets avg_frame_rate to 60000/1 for every DV profile, rather than the actual frame rate. This also affects Type 1 DV in AVI and leads to incorrect frame counts and progress estimates in applications such as HandBrake. Use the profile time base to derive avg_frame_rate, as is already done for packet duration and bitrate. Keep the stream time base unchanged. Add sample-free FATE tests for PAL, NTSC, 720p50 and 720p60 DV. Check the average frame rate, stream time base, packet timestamps and durations. All four tests fail before this change and pass with it. Fixes: c7a852b638b88f129790af31fc47c870c329eaaa Fixes: ticket #11339 Reported-by: Dave Rice Signed-off-by: FModel <[email protected]> --- libavformat/dv.c | 2 +- tests/fate/dvvideo.mak | 21 ++++++++++++++++++++- tests/ref/fate/dv-framerate-720p50 | 4 ++++ tests/ref/fate/dv-framerate-720p60 | 4 ++++ tests/ref/fate/dv-framerate-ntsc | 4 ++++ tests/ref/fate/dv-framerate-pal | 4 ++++ 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/dv-framerate-720p50 create mode 100644 tests/ref/fate/dv-framerate-720p60 create mode 100644 tests/ref/fate/dv-framerate-ntsc create mode 100644 tests/ref/fate/dv-framerate-pal diff --git a/libavformat/dv.c b/libavformat/dv.c index 84677284bdf..733e7093a10 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -319,7 +319,7 @@ static int dv_extract_video_info(DVDemuxContext *c, const uint8_t *frame) par = c->vst->codecpar; - c->vst->avg_frame_rate = av_inv_q(c->vst->time_base); + c->vst->avg_frame_rate = av_inv_q(c->sys->time_base); /* finding out SAR is a little bit messy */ vsc_pack = dv_extract_pack(frame, DV_VIDEO_CONTROL); diff --git a/tests/fate/dvvideo.mak b/tests/fate/dvvideo.mak index 33686d7762b..5656cfa21f8 100644 --- a/tests/fate/dvvideo.mak +++ b/tests/fate/dvvideo.mak @@ -5,4 +5,23 @@ fate-bsf-dv-error-marker: REF = 3190a334b1ceef2d9fd050a1590da7c6 FATE_DVVIDEO-$(call ALLYES, MOV_DEMUXER DV_ERROR_MARKER_BSF NOISE_BSF AVI_MUXER) += fate-bsf-dv-error-marker FATE_SAMPLES_FFMPEG += $(FATE_DVVIDEO-yes) -fate-dvvideo: $(FATE_DVVIDEO-yes) + +FATE_DVVIDEO_PROBE-$(call ENCDEC, DVVIDEO, DV, LAVFI_INDEV TESTSRC2_FILTER SCALE_FILTER \ + FORMAT_FILTER WRAPPED_AVFRAME_DECODER) += fate-dv-framerate-pal \ + fate-dv-framerate-ntsc \ + fate-dv-framerate-720p50 \ + fate-dv-framerate-720p60 + +fate-dv-framerate-pal: DV_OPTS = -s 720x576 -r 25 -pix_fmt yuv420p +fate-dv-framerate-ntsc: DV_OPTS = -s 720x480 -r 30000/1001 -pix_fmt yuv411p +fate-dv-framerate-720p50: DV_OPTS = -s 960x720 -r 50 -pix_fmt yuv422p +fate-dv-framerate-720p60: DV_OPTS = -s 960x720 -r 60000/1001 -pix_fmt yuv422p + +$(FATE_DVVIDEO_PROBE-yes): CMD = run_with_temp \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error -f lavfi -i testsrc2 -frames:v 3 \ + -c:v dvvideo $(DV_OPTS) -threads 1 -flags +bitexact -fflags +bitexact -f dv -y" \ + "ffprobe$(PROGSSUF)$(EXESUF) -v error -bitexact -select_streams v \ + -show_entries stream=avg_frame_rate,time_base:packet=pts,duration -of compact" dv + +FATE_FFMPEG_FFPROBE += $(FATE_DVVIDEO_PROBE-yes) +fate-dvvideo: $(FATE_DVVIDEO-yes) $(FATE_DVVIDEO_PROBE-yes) diff --git a/tests/ref/fate/dv-framerate-720p50 b/tests/ref/fate/dv-framerate-720p50 new file mode 100644 index 00000000000..a91ae11921b --- /dev/null +++ b/tests/ref/fate/dv-framerate-720p50 @@ -0,0 +1,4 @@ +packet|pts=0|duration=1200 +packet|pts=1200|duration=1200 +packet|pts=2400|duration=1200 +stream|avg_frame_rate=50/1|time_base=1/60000 diff --git a/tests/ref/fate/dv-framerate-720p60 b/tests/ref/fate/dv-framerate-720p60 new file mode 100644 index 00000000000..36309615f15 --- /dev/null +++ b/tests/ref/fate/dv-framerate-720p60 @@ -0,0 +1,4 @@ +packet|pts=0|duration=1001 +packet|pts=1001|duration=1001 +packet|pts=2002|duration=1001 +stream|avg_frame_rate=60000/1001|time_base=1/60000 diff --git a/tests/ref/fate/dv-framerate-ntsc b/tests/ref/fate/dv-framerate-ntsc new file mode 100644 index 00000000000..273f1020902 --- /dev/null +++ b/tests/ref/fate/dv-framerate-ntsc @@ -0,0 +1,4 @@ +packet|pts=0|duration=2002 +packet|pts=2002|duration=2002 +packet|pts=4004|duration=2002 +stream|avg_frame_rate=30000/1001|time_base=1/60000 diff --git a/tests/ref/fate/dv-framerate-pal b/tests/ref/fate/dv-framerate-pal new file mode 100644 index 00000000000..8273a819718 --- /dev/null +++ b/tests/ref/fate/dv-framerate-pal @@ -0,0 +1,4 @@ +packet|pts=0|duration=2400 +packet|pts=2400|duration=2400 +packet|pts=4800|duration=2400 +stream|avg_frame_rate=25/1|time_base=1/60000 -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
