From 58ce6d50a0eaa218c4fc7b7aaeb32f45e5b0b0da Mon Sep 17 00:00:00 2001 From: Ilya Konstantinov Date: Tue, 16 Jun 2015 17:18:52 +0300 Subject: avfvideosrc: add frame rate range to caps When AVFoundation indicates a supported frame rate range, add it to the caps. This is important for devices such as the iPhone 6, which indicate a single AVFrameRateRange of 2fps - 60fps. https://bugzilla.gnome.org/show_bug.cgi?id=751048 --- sys/applemedia/avfvideosrc.m | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/sys/applemedia/avfvideosrc.m b/sys/applemedia/avfvideosrc.m index 00f5c6524..a033ac026 100644 --- a/sys/applemedia/avfvideosrc.m +++ b/sys/applemedia/avfvideosrc.m @@ -343,7 +343,6 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer }); } - #define GST_AVF_CAPS_NEW(format, w, h, fps_n, fps_d) \ (gst_caps_new_simple ("video/x-raw", \ "width", G_TYPE_INT, w, \ @@ -352,6 +351,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer "framerate", GST_TYPE_FRACTION, (fps_n), (fps_d), \ NULL)) +#define GST_AVF_FPS_RANGE_CAPS_NEW(format, w, h, min_fps_n, min_fps_d, max_fps_n, max_fps_d) \ + (gst_caps_new_simple ("video/x-raw", \ + "width", G_TYPE_INT, w, \ + "height", G_TYPE_INT, h, \ + "format", G_TYPE_STRING, gst_video_format_to_string (format), \ + "framerate", GST_TYPE_FRACTION_RANGE, (min_fps_n), (min_fps_d), (max_fps_n), (max_fps_d), \ + NULL)) + - (GstVideoFormat)getGstVideoFormat:(NSNumber *)pixel_format { GstVideoFormat gst_format = GST_VIDEO_FORMAT_UNKNOWN; @@ -419,19 +426,30 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer formatDescription = (CMFormatDescriptionRef) [f performSelector:@selector(formatDescription)]; dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); for (NSObject *rate in [f valueForKey:@"videoSupportedFrameRateRanges"]) { - int fps_n, fps_d; - gdouble max_fps; + int min_fps_n, min_fps_d, max_fps_n, max_fps_d; + gdouble min_fps, max_fps; + + [[rate valueForKey:@"minFrameRate"] getValue:&min_fps]; + gst_util_double_to_fraction (min_fps, &min_fps_n, &min_fps_d); [[rate valueForKey:@"maxFrameRate"] getValue:&max_fps]; - gst_util_double_to_fraction (max_fps, &fps_n, &fps_d); + gst_util_double_to_fraction (max_fps, &max_fps_n, &max_fps_d); for (NSNumber *pixel_format in pixel_formats) { GstVideoFormat gst_format = [self getGstVideoFormat:pixel_format]; - if (gst_format != GST_VIDEO_FORMAT_UNKNOWN) - gst_caps_append (result, GST_AVF_CAPS_NEW (gst_format, dimensions.width, dimensions.height, fps_n, fps_d)); + if (gst_format != GST_VIDEO_FORMAT_UNKNOWN) { + if (min_fps != max_fps) + gst_caps_append (result, GST_AVF_FPS_RANGE_CAPS_NEW (gst_format, dimensions.width, dimensions.height, min_fps_n, min_fps_d, max_fps_n, max_fps_d)); + else + gst_caps_append (result, GST_AVF_CAPS_NEW (gst_format, dimensions.width, dimensions.height, max_fps_n, max_fps_d)); + } if (gst_format == GST_VIDEO_FORMAT_BGRA) { - GstCaps *rgba_caps = GST_AVF_CAPS_NEW (GST_VIDEO_FORMAT_RGBA, dimensions.width, dimensions.height, fps_n, fps_d); + GstCaps *rgba_caps; + if (min_fps != max_fps) + rgba_caps = GST_AVF_FPS_RANGE_CAPS_NEW (GST_VIDEO_FORMAT_RGBA, dimensions.width, dimensions.height, min_fps_n, min_fps_d, max_fps_n, max_fps_d); + else + rgba_caps = GST_AVF_CAPS_NEW (GST_VIDEO_FORMAT_RGBA, dimensions.width, dimensions.height, max_fps_n, max_fps_d); gst_caps_set_features (rgba_caps, 0, gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL)); gst_caps_append (result, rgba_caps); } @@ -462,10 +480,12 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer found_format = TRUE; [device setValue:f forKey:@"activeFormat"]; for (NSObject *rate in [f valueForKey:@"videoSupportedFrameRateRanges"]) { - gdouble max_frame_rate; + gdouble min_frame_rate, max_frame_rate; + [[rate valueForKey:@"minFrameRate"] getValue:&min_frame_rate]; [[rate valueForKey:@"maxFrameRate"] getValue:&max_frame_rate]; - if (fabs (framerate - max_frame_rate) < 0.00001) { + if ((framerate >= min_frame_rate - 0.00001) && + (framerate <= max_frame_rate + 0.00001)) { NSValue *min_frame_duration, *max_frame_duration; found_framerate = TRUE; -- cgit v1.2.1