Skip to content

Commit 1e0dca4

Browse files
Remove deprecated ticks_per_frame (#432)
Co-authored-by: Ian Butterworth <[email protected]>
1 parent ce0f8de commit 1e0dca4

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/avio.jl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,14 +431,26 @@ Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
431431
=#
432432
function framerate(f::VideoReader)
433433
# Try codec_context time_base first
434+
# NOTE: In modern FFmpeg (4+), codec_context.time_base is primarily used for encoding
435+
# and is marked as unused (and is often 0/1) for decoding. This path may not be reachable with modern video files.
436+
# The fallback paths below using stream.r_frame_rate/avg_frame_rate are more reliable.
437+
# See: https://ffmpeg.org/doxygen/trunk/structAVCodecContext.html#ab7bfeb9fa5840aac090e2b0bd0ef7589
434438
tb = f.codec_context.time_base
435439
if tb.num != 0
436-
fps = tb.den // tb.num // f.codec_context.ticks_per_frame
440+
# FFmpeg 8+ deprecated ticks_per_frame in favor of AV_CODEC_PROP_FIELDS for decoding.
441+
# See: https://github.com/FFmpeg/FFmpeg/commit/7d1d61cc5f57708434ba720b03234b3dd93a4d1e
442+
# For field-based codecs (H.264/MPEG-2), the time_base represents field duration,
443+
# so we divide by 2 to get frame rate. Check AV_CODEC_PROP_FIELDS flag via codec_descriptor.
444+
ticks = 1 # default for progressive video
445+
if f.codec_context.codec_descriptor != C_NULL
446+
ticks = (f.codec_context.codec_descriptor.props & AV_CODEC_PROP_FIELDS) == 0 ? 1 : 2
447+
end
448+
fps = tb.den // tb.num // ticks
437449
if isfinite(fps) && fps > 0
438450
return fps
439451
end
440452
end
441-
453+
442454
# Fallback to stream r_frame_rate if codec_context time_base is invalid
443455
stream = f.avin.format_context.streams[f.stream_index0 + 1]
444456
rfr = stream.r_frame_rate
@@ -448,7 +460,7 @@ function framerate(f::VideoReader)
448460
return fps
449461
end
450462
end
451-
463+
452464
# Last resort: try avg_frame_rate
453465
afr = stream.avg_frame_rate
454466
if afr.den != 0
@@ -457,7 +469,7 @@ function framerate(f::VideoReader)
457469
return fps
458470
end
459471
end
460-
472+
461473
# If all else fails, throw an error
462474
error("Unable to determine valid framerate from codec_context.time_base, stream.r_frame_rate, or stream.avg_frame_rate")
463475
end

0 commit comments

Comments
 (0)