Browse Source

mac-virtualcam: Pool pixel buffers

This change updates the mac-virtualcam implementation to pool the
CVPixelBuffers used to share the output frames. This allows the plugin
to recycle the pixel buffers used by the plugin.
Fabian Mastenbroek 3 years ago
parent
commit
29ca91852b
1 changed files with 25 additions and 9 deletions
  1. 25 9
      plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm

+ 25 - 9
plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm

@@ -12,6 +12,7 @@ MODULE_EXPORT const char *obs_module_description(void)
 
 obs_output_t *outputRef;
 obs_video_info videoInfo;
+CVPixelBufferPoolRef pool;
 static OBSDALMachServer *sMachServer;
 
 static bool check_dal_plugin()
@@ -145,10 +146,27 @@ static bool virtualcam_output_start(void *data)
 
 	blog(LOG_DEBUG, "output_start");
 
-	[sMachServer run];
-
 	obs_get_video_info(&videoInfo);
 
+	NSDictionary *pAttr = @{};
+	NSDictionary *pbAttr = @{
+		(id)kCVPixelBufferPixelFormatTypeKey:
+			@(kCVPixelFormatType_422YpCbCr8),
+		(id)kCVPixelBufferWidthKey: @(videoInfo.output_width),
+		(id)kCVPixelBufferHeightKey: @(videoInfo.output_height),
+		(id)kCVPixelBufferIOSurfacePropertiesKey: @{}
+	};
+	CVReturn status = CVPixelBufferPoolCreate(
+		kCFAllocatorDefault, (__bridge CFDictionaryRef)pAttr,
+		(__bridge CFDictionaryRef)pbAttr, &pool);
+	if (status != kCVReturnSuccess) {
+		blog(LOG_ERROR,
+		     "unable to allocate pixel buffer pool (error %d)", status);
+		return false;
+	}
+
+	[sMachServer run];
+
 	struct video_scale_info conversion = {};
 	conversion.format = VIDEO_FORMAT_UYVY;
 	conversion.width = videoInfo.output_width;
@@ -169,6 +187,8 @@ static void virtualcam_output_stop(void *data, uint64_t ts)
 	blog(LOG_DEBUG, "output_stop");
 	obs_output_end_data_capture(outputRef);
 	[sMachServer stop];
+
+	CVPixelBufferPoolRelease(pool);
 }
 
 static void virtualcam_output_raw_video(void *data, struct video_data *frame)
@@ -182,15 +202,11 @@ static void virtualcam_output_raw_video(void *data, struct video_data *frame)
 		     (videoInfo.output_width * 2), frame->linesize[0]);
 	}
 
-	size_t width = videoInfo.output_width;
 	size_t height = videoInfo.output_height;
 
-	NSDictionary *pbAttr = @{(id)kCVPixelBufferIOSurfacePropertiesKey: @{}};
 	CVPixelBufferRef frameRef = NULL;
-	CVReturn status = CVPixelBufferCreate(NULL, width, height,
-					      kCVPixelFormatType_422YpCbCr8,
-					      (__bridge CFDictionaryRef)pbAttr,
-					      &frameRef);
+	CVReturn status =
+		CVPixelBufferPoolCreatePixelBuffer(NULL, pool, &frameRef);
 
 	if (status != kCVReturnSuccess) {
 		blog(LOG_ERROR, "unable to allocate pixel buffer (error %d)",
@@ -214,7 +230,7 @@ static void virtualcam_output_raw_video(void *data, struct video_data *frame)
 	if (destBytesPerRow == srcBytesPerRow) {
 		memcpy(dest, src, destBytesPerRow * height);
 	} else {
-		for (int line = 0; line < height; line++) {
+		for (int line = 0; (size_t)line < height; line++) {
 			memcpy(dest, src, srcBytesPerRow);
 			src += srcBytesPerRow;
 			dest += destBytesPerRow;