From 86e25398161824c6d2ce673180bc8883e74e8065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 4 Nov 2010 17:47:25 +0100 Subject: [PATCH] qtkitvideosrc: implement zero-copy by using buffer-factory This means we'll wrap each CoreVideo buffer inside a GstBuffer instead of making a copy. --- sys/applemedia/qtkitvideosrc.m | 44 ++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/sys/applemedia/qtkitvideosrc.m b/sys/applemedia/qtkitvideosrc.m index b50acf32b2..786188f571 100644 --- a/sys/applemedia/qtkitvideosrc.m +++ b/sys/applemedia/qtkitvideosrc.m @@ -19,6 +19,8 @@ #include "qtkitvideosrc.h" +#import "bufferfactory.h" + #import #define DEFAULT_DEVICE_INDEX -1 @@ -100,6 +102,7 @@ static GstPushSrcClass * parent_class; int deviceIndex; + GstAMBufferFactory *bufferFactory; QTCaptureSession *session; QTCaptureDeviceInput *input; QTCaptureDecompressedVideoOutput *output; @@ -166,24 +169,31 @@ static GstPushSrcClass * parent_class; - (BOOL)openDevice { - NSString *mediaType; + GError *gerror; + NSString *mediaType = QTMediaTypeVideo; NSError *error = nil; - mediaType = QTMediaTypeVideo; + bufferFactory = [[GstAMBufferFactory alloc] initWithError:&gerror]; + if (bufferFactory == nil) { + GST_ELEMENT_ERROR (element, RESOURCE, FAILED, ("API error"), + ("%s", gerror->message)); + g_clear_error (&gerror); + goto openFailed; + } if (deviceIndex == -1) { device = [QTCaptureDevice defaultInputDeviceWithMediaType:mediaType]; if (device == nil) { GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND, ("No video capture devices found"), (NULL)); - return NO; + goto openFailed; } } else { NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:mediaType]; if (deviceIndex >= [devices count]) { GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND, ("Invalid video capture device index"), (NULL)); - return NO; + goto openFailed; } device = [devices objectAtIndex:deviceIndex]; } @@ -195,12 +205,22 @@ static GstPushSrcClass * parent_class; GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND, ("Failed to open device '%s'", [[device localizedDisplayName] UTF8String]), (NULL)); - [device release]; - device = nil; - return NO; + goto openFailed; } return YES; + + /* ERRORS */ +openFailed: + { + [device release]; + device = nil; + + [bufferFactory release]; + bufferFactory = nil; + + return NO; + } } - (void)closeDevice @@ -218,6 +238,9 @@ static GstPushSrcClass * parent_class; [device release]; device = nil; + + [bufferFactory release]; + bufferFactory = nil; } - (BOOL)setCaps:(GstCaps *)caps @@ -383,12 +406,7 @@ static GstPushSrcClass * parent_class; [queueLock unlockWithCondition: ([queue count] == 0) ? NO_FRAMES : HAS_FRAME_OR_STOP_REQUEST]; - *buf = gst_buffer_new_and_alloc ( - CVPixelBufferGetBytesPerRow (frame) * CVPixelBufferGetHeight (frame)); - CVPixelBufferLockBaseAddress (frame, 0); - memcpy (GST_BUFFER_DATA (*buf), CVPixelBufferGetBaseAddress (frame), - GST_BUFFER_SIZE (*buf)); - CVPixelBufferUnlockBaseAddress (frame, 0); + *buf = [bufferFactory createGstBufferForCoreVideoBuffer:frame]; CVBufferRelease (frame); [self timestampBuffer:*buf];