caopengllayer: prepare color space handling
authorFelix Paul Kühne <fkuehne@videolan.org>
Sat, 16 Apr 2016 11:30:38 +0000 (14:30 +0300)
committerFelix Paul Kühne <fkuehne@videolan.org>
Sat, 16 Apr 2016 12:15:03 +0000 (15:15 +0300)
modules/video_output/caopengllayer.m

index c8dfd65..787bd45 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * caopengllayer.m: CAOpenGLLayer (Mac OS X) video output
  *****************************************************************************
- * Copyright (C) 2014-2015 VLC authors and VideoLAN
+ * Copyright (C) 2014-2016 VLC authors and VideoLAN
  * $Id$
  *
  * Authors: David Fuhrmann <david dot fuhrmann at googlemail dot com>
@@ -43,6 +43,8 @@
 
 #include "opengl.h"
 
+#define OSX_EL_CAPITAN (NSAppKitVersionNumber >= 1404)
+
 /*****************************************************************************
  * Vout interface
  *****************************************************************************/
@@ -57,7 +59,6 @@ vlc_module_begin()
     set_callbacks(Open, Close)
 vlc_module_end()
 
-
 static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count);
 static void PictureRender   (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture);
 static void PictureDisplay  (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture);
@@ -90,6 +91,8 @@ struct vout_display_sys_t {
     vout_window_t *embed;
     VLCCAOpenGLLayer *cgLayer;
 
+    CGColorSpaceRef cgColorSpace;
+
     CGLContextObj glContext;
 
     vlc_gl_t gl;
@@ -188,6 +191,34 @@ static int Open (vlc_object_t *p_this)
         vd->display = PictureDisplay;
         vd->control = Control;
 
+        /* handle color space if supported by the OS */
+        if ([sys->cgLayer respondsToSelector:@selector(setColorspace:)]) {
+
+            /* support for BT.709 and BT.2020 color spaces was introduced with OS X 10.11
+             * on older OS versions, we can't show correct colors, so we fallback on linear RGB */
+            if (OSX_EL_CAPITAN) {
+                msg_Warn(vd, "Guessing color space based on video dimensions (height: %i", fmt.i_height);
+
+                if (fmt.i_height >= 2000 || fmt.i_width >= 3800) {
+                    msg_Dbg(vd, "Should use BT.2020 color space, but in reality it's BT.709");
+                    sys->cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceITUR_709);
+                } else if (fmt.i_height > 576) {
+                    msg_Dbg(vd, "Using BT.709 color space");
+                    sys->cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceITUR_709);
+                } else {
+                    msg_Dbg(vd, "SD content, using linear RGB color space");
+                    sys->cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
+                }
+            } else {
+                msg_Dbg(vd, "OS does not support BT.709 or BT.2020 color spaces, output may vary");
+                sys->cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+            }
+
+            [sys->cgLayer setColorspace: sys->cgColorSpace];
+        } else {
+            msg_Dbg(vd, "OS does not support custom color spaces, output may be undefined");
+        }
+
         /* setup initial state */
         CGSize outputSize;
         if ([container respondsToSelector:@selector(currentOutputSize)])
@@ -230,6 +261,9 @@ static void Close (vlc_object_t *p_this)
     if (sys->glContext)
         CGLReleaseContext(sys->glContext);
 
+    if (sys->cgColorSpace != nil)
+        CGColorSpaceRelease(sys->cgColorSpace);
+
     free(sys);
 }
 
@@ -447,6 +481,12 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
     sys->b_frame_available = NO;
 }
 
+-(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+    // The default is fine for this demonstration.
+    return [super copyCGLPixelFormatForDisplayMask:mask];
+}
+
 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
 {
     // Only one opengl context is allowed for the module lifetime