[vlc-commits] videotoolbox: add support for zero-copy rendering

Felix Paul Kühne git at videolan.org
Fri Aug 21 19:10:32 CEST 2015


vlc | branch: master | Felix Paul Kühne <fkuehne at videolan.org> | Thu Aug 20 18:48:49 2015 +0200| [bb27e69338c8cf74fe938513f2015d5566d16e19] | committer: Felix Paul Kühne

videotoolbox: add support for zero-copy rendering

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bb27e69338c8cf74fe938513f2015d5566d16e19
---

 modules/codec/videotoolbox.m |   48 +++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index e1ac985..2e89f3c 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -52,6 +52,7 @@ const CFStringRef kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDec
 const CFStringRef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder = CFSTR("RequireHardwareAcceleratedVideoDecoder");
 #endif
 
+#define VT_ZERO_COPY N_("Use zero-copy rendering")
 #if !TARGET_OS_IPHONE
 #define VT_REQUIRE_HW_DEC N_("Use Hardware decoders only")
 #endif
@@ -62,8 +63,12 @@ set_subcategory(SUBCAT_INPUT_VCODEC)
 set_description(N_("VideoToolbox video decoder"))
 set_capability("decoder",800)
 set_callbacks(OpenDecoder, CloseDecoder)
+
 #if !TARGET_OS_IPHONE
+add_bool("videotoolbox-zero-copy", false, VT_ZERO_COPY, VT_ZERO_COPY, false)
 add_bool("videotoolbox-hw-decoder-only", false, VT_REQUIRE_HW_DEC, VT_REQUIRE_HW_DEC, false)
+#else
+add_bool("videotoolbox-zero-copy", true, VT_ZERO_COPY, VT_ZERO_COPY, false)
 #endif
 vlc_module_end()
 
@@ -78,6 +83,10 @@ static void copy420YpCbCr8Planar(picture_t *, CVPixelBufferRef buffer,
                                  unsigned i_width, unsigned i_height);
 static BOOL deviceSupportsAdvancedProfiles();
 
+struct picture_sys_t {
+    CFTypeRef pixelBuffer;
+};
+
 #pragma mark - decoder structure
 
 struct decoder_sys_t
@@ -94,6 +103,7 @@ struct decoder_sys_t
 
     NSMutableArray              *outputTimeStamps;
     NSMutableDictionary         *outputFrames;
+    bool                        b_zero_copy;
 };
 
 #pragma mark - start & stop
@@ -445,6 +455,8 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
         return VLC_EGENERIC;
     }
 
+    p_sys->b_zero_copy = var_InheritInteger(p_dec, "videotoolbox-zero-copy");
+
     /* destination pixel buffer attributes */
     CFMutableDictionaryRef dpba = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                             2,
@@ -459,7 +471,7 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
 #else
     CFDictionarySetValue(dpba,
                          kCVPixelBufferOpenGLESCompatibilityKey,
-                         kCFBooleanFalse);
+                         kCFBooleanTrue);
 #endif
     VTDictionarySetInt32(dpba,
                          kCVPixelBufferPixelFormatTypeKey,
@@ -615,7 +627,10 @@ static int OpenDecoder(vlc_object_t *p_this)
 
     /* return our proper VLC internal state */
     p_dec->fmt_out.i_cat = VIDEO_ES;
-    p_dec->fmt_out.i_codec = VLC_CODEC_I420;
+    if (p_sys->b_zero_copy)
+        p_dec->fmt_out.i_codec = VLC_CODEC_CVPX_OPAQUE;
+    else
+        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
 
     p_dec->b_need_packetized = true;
 
@@ -875,10 +890,16 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
 
     p_block = *pp_block;
 
-    if (likely(p_block)) {
+    if (likely(p_block != NULL)) {
         if (unlikely(p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))) {
-            [p_sys->outputTimeStamps removeAllObjects];
-            [p_sys->outputFrames removeAllObjects];
+            if (likely(p_sys->b_started)) {
+                @synchronized(p_sys->outputTimeStamps) {
+                    [p_sys->outputTimeStamps removeAllObjects];
+                }
+                @synchronized(p_sys->outputFrames) {
+                    [p_sys->outputFrames removeAllObjects];
+                }
+            }
             block_Release(p_block);
             goto skip;
         }
@@ -988,11 +1009,18 @@ skip:
                 if (!p_pic)
                     return NULL;
 
-                /* ehm, *cough*, memcpy.. */
-                copy420YpCbCr8Planar(p_pic,
-                                     imageBuffer,
-                                     CVPixelBufferGetWidthOfPlane(imageBuffer, 0),
-                                     CVPixelBufferGetHeightOfPlane(imageBuffer, 0));
+                if (!p_sys->b_zero_copy) {
+                    /* ehm, *cough*, memcpy.. */
+                    copy420YpCbCr8Planar(p_pic,
+                                         imageBuffer,
+                                         CVPixelBufferGetWidthOfPlane(imageBuffer, 0),
+                                         CVPixelBufferGetHeightOfPlane(imageBuffer, 0));
+                } else {
+                    p_pic->p_sys = malloc(sizeof(picture_sys_t));
+                    if (p_pic->p_sys)
+                        p_pic->p_sys->pixelBuffer = CFBridgingRetain(imageBufferObject);
+                    /* will be freed by the vout */
+                }
 
                 p_pic->date = timeStamp.longLongValue;
 



More information about the vlc-commits mailing list