mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
qtkitvideosrc: implement zero-copy by using buffer-factory
This means we'll wrap each CoreVideo buffer inside a GstBuffer instead of making a copy.
This commit is contained in:
parent
835b2988b6
commit
86e2539816
1 changed files with 31 additions and 13 deletions
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "qtkitvideosrc.h"
|
#include "qtkitvideosrc.h"
|
||||||
|
|
||||||
|
#import "bufferfactory.h"
|
||||||
|
|
||||||
#import <QTKit/QTKit.h>
|
#import <QTKit/QTKit.h>
|
||||||
|
|
||||||
#define DEFAULT_DEVICE_INDEX -1
|
#define DEFAULT_DEVICE_INDEX -1
|
||||||
|
@ -100,6 +102,7 @@ static GstPushSrcClass * parent_class;
|
||||||
|
|
||||||
int deviceIndex;
|
int deviceIndex;
|
||||||
|
|
||||||
|
GstAMBufferFactory *bufferFactory;
|
||||||
QTCaptureSession *session;
|
QTCaptureSession *session;
|
||||||
QTCaptureDeviceInput *input;
|
QTCaptureDeviceInput *input;
|
||||||
QTCaptureDecompressedVideoOutput *output;
|
QTCaptureDecompressedVideoOutput *output;
|
||||||
|
@ -166,24 +169,31 @@ static GstPushSrcClass * parent_class;
|
||||||
|
|
||||||
- (BOOL)openDevice
|
- (BOOL)openDevice
|
||||||
{
|
{
|
||||||
NSString *mediaType;
|
GError *gerror;
|
||||||
|
NSString *mediaType = QTMediaTypeVideo;
|
||||||
NSError *error = nil;
|
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) {
|
if (deviceIndex == -1) {
|
||||||
device = [QTCaptureDevice defaultInputDeviceWithMediaType:mediaType];
|
device = [QTCaptureDevice defaultInputDeviceWithMediaType:mediaType];
|
||||||
if (device == nil) {
|
if (device == nil) {
|
||||||
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
||||||
("No video capture devices found"), (NULL));
|
("No video capture devices found"), (NULL));
|
||||||
return NO;
|
goto openFailed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:mediaType];
|
NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:mediaType];
|
||||||
if (deviceIndex >= [devices count]) {
|
if (deviceIndex >= [devices count]) {
|
||||||
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
||||||
("Invalid video capture device index"), (NULL));
|
("Invalid video capture device index"), (NULL));
|
||||||
return NO;
|
goto openFailed;
|
||||||
}
|
}
|
||||||
device = [devices objectAtIndex:deviceIndex];
|
device = [devices objectAtIndex:deviceIndex];
|
||||||
}
|
}
|
||||||
|
@ -195,12 +205,22 @@ static GstPushSrcClass * parent_class;
|
||||||
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
||||||
("Failed to open device '%s'",
|
("Failed to open device '%s'",
|
||||||
[[device localizedDisplayName] UTF8String]), (NULL));
|
[[device localizedDisplayName] UTF8String]), (NULL));
|
||||||
[device release];
|
goto openFailed;
|
||||||
device = nil;
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
openFailed:
|
||||||
|
{
|
||||||
|
[device release];
|
||||||
|
device = nil;
|
||||||
|
|
||||||
|
[bufferFactory release];
|
||||||
|
bufferFactory = nil;
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)closeDevice
|
- (void)closeDevice
|
||||||
|
@ -218,6 +238,9 @@ static GstPushSrcClass * parent_class;
|
||||||
|
|
||||||
[device release];
|
[device release];
|
||||||
device = nil;
|
device = nil;
|
||||||
|
|
||||||
|
[bufferFactory release];
|
||||||
|
bufferFactory = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)setCaps:(GstCaps *)caps
|
- (BOOL)setCaps:(GstCaps *)caps
|
||||||
|
@ -383,12 +406,7 @@ static GstPushSrcClass * parent_class;
|
||||||
[queueLock unlockWithCondition:
|
[queueLock unlockWithCondition:
|
||||||
([queue count] == 0) ? NO_FRAMES : HAS_FRAME_OR_STOP_REQUEST];
|
([queue count] == 0) ? NO_FRAMES : HAS_FRAME_OR_STOP_REQUEST];
|
||||||
|
|
||||||
*buf = gst_buffer_new_and_alloc (
|
*buf = [bufferFactory createGstBufferForCoreVideoBuffer:frame];
|
||||||
CVPixelBufferGetBytesPerRow (frame) * CVPixelBufferGetHeight (frame));
|
|
||||||
CVPixelBufferLockBaseAddress (frame, 0);
|
|
||||||
memcpy (GST_BUFFER_DATA (*buf), CVPixelBufferGetBaseAddress (frame),
|
|
||||||
GST_BUFFER_SIZE (*buf));
|
|
||||||
CVPixelBufferUnlockBaseAddress (frame, 0);
|
|
||||||
CVBufferRelease (frame);
|
CVBufferRelease (frame);
|
||||||
|
|
||||||
[self timestampBuffer:*buf];
|
[self timestampBuffer:*buf];
|
||||||
|
|
Loading…
Reference in a new issue