introduce -video_size
if not provided use the first size available
---
 libavdevice/avfoundation_dec.m | 66 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/libavdevice/avfoundation_dec.m b/libavdevice/avfoundation_dec.m
index 7c0212a..ce04f33 100644
--- a/libavdevice/avfoundation_dec.m
+++ b/libavdevice/avfoundation_dec.m
@@ -30,6 +30,7 @@
 #include "libavformat/internal.h"
 #include "libavutil/time.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
 
 #include "avdevice.h"
 
@@ -93,8 +94,10 @@ typedef struct AVFoundationCaptureContext {
     int list_devices;
     int list_formats;
     char* pixel_format;
+    char *video_size;   /* String describing video size */
 
     int video_stream_index;
+    int width, height;
 
     int64_t first_pts;
     int frames_captured;
@@ -121,6 +124,7 @@ static const AVOption options[] = {
     { "video",        "Show only the video devices",     OFFSET(list_devices), 
AV_OPT_TYPE_CONST,  {.i64 = VIDEO_DEVICES }, 0, INT_MAX, DEC, "list_devices" },
     { "list_formats", "List available formats and exit", OFFSET(list_formats), 
AV_OPT_TYPE_INT,    {.i64 = 0 },             0, INT_MAX, DEC, "list_formats" },
     { "pixel_format", "Preferred pixel format",          OFFSET(pixel_format), 
AV_OPT_TYPE_STRING, {.str = NULL},           0, 0, DEC},
+    { "video_size",   "A string describing frame size, such as 640x480 or 
hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0, DEC },
     { NULL },
 };
 
@@ -226,6 +230,51 @@ static void unlock_frames(AVFoundationCaptureContext* ctx)
 
 @end
 
+/**
+ * Configure the video device.
+ */
+static bool configure_video_device(AVFormatContext *s, AVCaptureDevice 
*video_device)
+{
+    AVFoundationCaptureContext *ctx = s->priv_data;
+    AVCaptureDeviceFormat* selected_format = nil;
+
+    for (AVCaptureDeviceFormat* format in [video_device formats]) {
+        CMFormatDescriptionRef formatDescription;
+        CMVideoDimensions dimensions;
+
+        formatDescription = (CMFormatDescriptionRef) format.formatDescription;
+        dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
+
+        if ((ctx->width == 0 && ctx->height == 0) ||
+            (dimensions.width == ctx->width && dimensions.height == 
ctx->height)) {
+
+            av_log(s, AV_LOG_INFO, "Video size (%dx%d) supported\n",
+                dimensions.width, dimensions.height);
+            ctx->width = dimensions.width;
+            ctx->height = dimensions.height;
+            selected_format = format;
+            break;
+        }
+    }
+
+    if (!selected_format) {
+        av_log(s, AV_LOG_ERROR, "Selected video size (%dx%d) is not supported 
by the device\n",
+            ctx->width, ctx->height);
+        return false;
+    } else {
+        av_log(s, AV_LOG_INFO, "Setting video size to %dx%d\n",
+            ctx->width, ctx->height);
+    }
+
+    if ([video_device lockForConfiguration:NULL] == YES) {
+        [video_device setActiveFormat:selected_format];
+    } else {
+        av_log(s, AV_LOG_ERROR, "Could not lock device for configuration");
+        return false;
+    }
+    return true;
+}
+
 static int setup_stream(AVFormatContext *s, AVCaptureDevice *device)
 {
     av_log(s, AV_LOG_INFO, "Setting up stream for device %s\n", [[device 
uniqueID] UTF8String]);
@@ -236,6 +285,12 @@ static int setup_stream(AVFormatContext *s, 
AVCaptureDevice *device)
     AVCaptureSession *session = (__bridge AVCaptureSession*)ctx->session;
     input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                   error:&error];
+
+    if (!configure_video_device(s, device)) {
+        av_log(s, AV_LOG_ERROR, "device configuration failed\n");
+        return AVERROR(EINVAL);
+    }
+
     // add the input devices
     if (!input) {
         av_log(s, AV_LOG_ERROR, "%s\n",
@@ -456,13 +511,16 @@ static int setup_streams(AVFormatContext *s)
     }
 
     if (ret < 0) {
-        av_log(s, AV_LOG_ERROR, "No device could be added");
+        av_log(s, AV_LOG_ERROR, "No device could be added\n");
         return ret;
     }
 
     av_log(s, AV_LOG_INFO, "Starting session!\n");
     [(__bridge AVCaptureSession*)ctx->session startRunning];
 
+    // Session is started, unlock device
+    [device unlockForConfiguration];
+
     av_log(s, AV_LOG_INFO, "Checking video config\n");
     if (get_video_config(s)) {
         destroy_context(ctx);
@@ -491,6 +549,12 @@ static int avfoundation_read_header(AVFormatContext *s)
         }
     }
 
+    if (ctx->video_size &&
+        (av_parse_video_size(&ctx->width, &ctx->height, ctx->video_size)) < 0) 
{
+        av_log(s, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
+               ctx->video_size);
+        return AVERROR(EINVAL);
+    }
 
     return setup_streams(s);
 }
-- 
2.6.2

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to