PR #25425 opened by oppianmatt URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25425 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25425.patch
configure_video_device() selects a frame-rate range only when the requested rate equals that range's maxFrameRate. Some devices advertise one continuous range per format instead of one range per rate. The MacBook Pro FaceTime HD camera on macOS 26.5.1 can list "1280x720@[15.000000 30.000000]fps", and then -framerate 15 fails with "Selected framerate (15.000000) is not supported by the device" although 15 is inside the advertised range. Keep the exact max match first, so existing behaviour is unchanged. Failing that, accept a range that contains the requested rate, and set both activeVideoMinFrameDuration and activeVideoMaxFrameDuration to the requested rate rather than to the range's minimum duration. Tested on that camera at 1280x720 nv12, 10 s each: -framerate 15 now opens and delivers 150 frames (15.0 fps); -framerate 30 delivers 298-299 frames, as before. Signed-off-by: Matthew Jacobi <[email protected]> >From 94d5bbc0c106796e67d3076c224751f55d919467 Mon Sep 17 00:00:00 2001 From: Matthew Jacobi <[email protected]> Date: Sat, 24 Oct 2026 21:46:56 +0200 Subject: [PATCH] avdevice/avfoundation: accept a frame rate inside a continuous range configure_video_device() selects a frame-rate range only when the requested rate equals that range's maxFrameRate. Some devices advertise one continuous range per format instead of one range per rate. The MacBook Pro FaceTime HD camera on macOS 26.5.1 can list "1280x720@[15.000000 30.000000]fps", and then -framerate 15 fails with "Selected framerate (15.000000) is not supported by the device" although 15 is inside the advertised range. Keep the exact max match first, so existing behaviour is unchanged. Failing that, accept a range that contains the requested rate, and set both activeVideoMinFrameDuration and activeVideoMaxFrameDuration to the requested rate rather than to the range's minimum duration. Tested on that camera at 1280x720 nv12, 10 s each: -framerate 15 now opens and delivers 150 frames (15.0 fps); -framerate 30 delivers 298-299 frames, as before. Signed-off-by: Matthew Jacobi <[email protected]> --- libavdevice/avfoundation.m | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m index 8b7e728279e..68dcd1ee38c 100644 --- a/libavdevice/avfoundation.m +++ b/libavdevice/avfoundation.m @@ -397,6 +397,7 @@ static int configure_video_device(AVFormatContext *s, AVCaptureDevice *video_dev NSObject *matching_size_format = nil; NSObject *selected_range = nil; NSObject *selected_format = nil; + int inside_range = 0; // try to configure format by formats list // might raise an exception if no format list is given @@ -415,14 +416,25 @@ static int configure_video_device(AVFormatContext *s, AVCaptureDevice *video_dev matching_size_format = format; for (range in [format valueForKey:@"videoSupportedFrameRateRanges"]) { + double min_framerate; double max_framerate; + [[range valueForKey:@"minFrameRate"] getValue:&min_framerate]; [[range valueForKey:@"maxFrameRate"] getValue:&max_framerate]; if (fabs (framerate - max_framerate) < 0.01) { selected_format = format; selected_range = range; + inside_range = 0; break; } + // A device may advertise one continuous range (e.g. [15 30]) + // instead of one range per rate; any rate inside it is valid. + if (!selected_range && + framerate > min_framerate - 0.01 && framerate < max_framerate + 0.01) { + selected_format = format; + selected_range = range; + inside_range = 1; + } } } } @@ -449,9 +461,13 @@ static int configure_video_device(AVFormatContext *s, AVCaptureDevice *video_dev [video_device setValue:selected_format forKey:@"activeFormat"]; } if (selected_range) { - NSValue *min_frame_duration = [selected_range valueForKey:@"minFrameDuration"]; - [video_device setValue:min_frame_duration forKey:@"activeVideoMinFrameDuration"]; - [video_device setValue:min_frame_duration forKey:@"activeVideoMaxFrameDuration"]; + NSValue *frame_duration = [selected_range valueForKey:@"minFrameDuration"]; + if (inside_range) { + CMTime requested = CMTimeMake(ctx->framerate.den, ctx->framerate.num); + frame_duration = [NSValue valueWithCMTime:requested]; + } + [video_device setValue:frame_duration forKey:@"activeVideoMinFrameDuration"]; + [video_device setValue:frame_duration forKey:@"activeVideoMaxFrameDuration"]; } } else { av_log(s, AV_LOG_ERROR, "Could not lock device for configuration.\n"); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
