introduce -pixel_format
if not present override with the first available in video output
---
 libavdevice/avfoundation_dec.m | 56 ++++++++++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/libavdevice/avfoundation_dec.m b/libavdevice/avfoundation_dec.m
index 0a3f535..7c0212a 100644
--- a/libavdevice/avfoundation_dec.m
+++ b/libavdevice/avfoundation_dec.m
@@ -92,7 +92,7 @@ typedef struct AVFoundationCaptureContext {
     /* AVOptions */
     int list_devices;
     int list_formats;
-    enum AVPixelFormat pixel_format;
+    char* pixel_format;
 
     int video_stream_index;
 
@@ -119,7 +119,8 @@ static const AVOption options[] = {
     { "all",          "Show all the supported devices",  OFFSET(list_devices), 
AV_OPT_TYPE_CONST,  {.i64 = ALL_DEVICES },   0, INT_MAX, DEC, "list_devices" },
     { "audio",        "Show only the audio devices",     OFFSET(list_devices), 
AV_OPT_TYPE_CONST,  {.i64 = AUDIO_DEVICES }, 0, INT_MAX, DEC, "list_devices" },
     { "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" },
+    { "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},
     { NULL },
 };
 
@@ -159,7 +160,7 @@ static int list_formats(AVFormatContext *s)
     av_log(s, AV_LOG_VERBOSE, "Supported pixel formats (first is more 
efficient):\n");
     AVCaptureVideoDataOutput* out = [[AVCaptureVideoDataOutput alloc] init];
 
-    for (NSNumber *cv_pixel_format in [out availableVideoCVPixelFormatTypes]) {
+    for (NSNumber* cv_pixel_format in [out availableVideoCVPixelFormatTypes]) {
         OSType cv_fmt = [cv_pixel_format intValue];
         enum AVPixelFormat pix_fmt = core_video_to_pix_fmt(cv_fmt);
         if (pix_fmt != AV_PIX_FMT_NONE) {
@@ -253,7 +254,6 @@ static int setup_stream(AVFormatContext *s, AVCaptureDevice 
*device)
     if ([device hasMediaType:AVMediaTypeVideo]) {
         AVCaptureVideoDataOutput* out = [[AVCaptureVideoDataOutput alloc] 
init];
         NSNumber *core_video_fmt = nil;
-        enum AVPixelFormat pixel_format;
         if (!out) {
             av_log(s, AV_LOG_ERROR, "Failed to init AV video output\n");
             return -1;
@@ -261,17 +261,27 @@ static int setup_stream(AVFormatContext *s, 
AVCaptureDevice *device)
 
         [out setAlwaysDiscardsLateVideoFrames:YES];
 
-        // Map the first supported pixel format
-        av_log(s, AV_LOG_VERBOSE, "Supported pixel formats:\n");
-        for (NSNumber *cv_pixel_format in [out 
availableVideoCVPixelFormatTypes]) {
-            OSType cv_fmt = [cv_pixel_format intValue];
-            enum AVPixelFormat pix_fmt = core_video_to_pix_fmt(cv_fmt);
-            if (pix_fmt != AV_PIX_FMT_NONE) {
-                av_log(s, AV_LOG_VERBOSE, "  %s: %d\n",
-                       av_get_pix_fmt_name(pix_fmt),
-                       cv_fmt);
-                core_video_fmt = cv_pixel_format;
-                pixel_format   = pix_fmt;
+        if (ctx->pixel_format) {
+            // Try to use specified pixel format
+            core_video_fmt = [NSNumber 
numberWithInt:pix_fmt_to_core_video(av_get_pix_fmt(ctx->pixel_format))];
+            if ([[out availableVideoCVPixelFormatTypes] 
indexOfObject:core_video_fmt] != NSNotFound) {
+                av_log(s, AV_LOG_VERBOSE, "Pixel format %s supported!\n", 
ctx->pixel_format);
+            } else {
+                core_video_fmt = nil;
+            }
+        }
+
+        if (!ctx->pixel_format || !core_video_fmt) {
+            av_log(s, AV_LOG_VERBOSE, "Pixel format not supported or not 
provided, overriding...\n");
+            for (NSNumber *cv_pixel_format in [out 
availableVideoCVPixelFormatTypes]) {
+                OSType cv_fmt = [cv_pixel_format intValue];
+                enum AVPixelFormat pix_fmt = core_video_to_pix_fmt(cv_fmt);
+                // Use the first one in the list, it will be the most effective
+                if (pix_fmt != AV_PIX_FMT_NONE) {
+                    core_video_fmt = cv_pixel_format;
+                    ctx->pixel_format = 
av_strdup(av_get_pix_fmt_name(pix_fmt));;
+                    break;
+                }
             }
         }
 
@@ -279,10 +289,9 @@ static int setup_stream(AVFormatContext *s, 
AVCaptureDevice *device)
         if (!core_video_fmt) {
             return 1;
         } else {
-            av_log(s, AV_LOG_INFO, "Using %s.\n",
-                   av_get_pix_fmt_name(pixel_format));
+            av_log(s, AV_LOG_INFO, "Using %s.\n", ctx->pixel_format);
         }
-        ctx->pixel_format          = pixel_format;
+
         NSDictionary *capture_dict = [NSDictionary 
dictionaryWithObject:core_video_fmt
                                                                  
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
         [out setVideoSettings:capture_dict];
@@ -336,7 +345,7 @@ static int get_video_config(AVFormatContext *s)
     stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     stream->codec->width      = (int)image_buffer_size.width;
     stream->codec->height     = (int)image_buffer_size.height;
-    stream->codec->pix_fmt    = ctx->pixel_format;
+    stream->codec->pix_fmt    = av_get_pix_fmt(ctx->pixel_format);
 
     CFRelease(ctx->current_frame);
     ctx->current_frame = nil;
@@ -474,6 +483,15 @@ static int avfoundation_read_header(AVFormatContext *s)
         return list_formats(s);
     }
 
+    if (ctx->pixel_format) {
+        if (av_get_pix_fmt(ctx->pixel_format) == AV_PIX_FMT_NONE) {
+            av_log(s, AV_LOG_ERROR, "No such input format: %s.\n",
+                   ctx->pixel_format);
+            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