mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
avfvideosrc: Allow specifying crop coordinates during screen capture
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3153>
This commit is contained in:
parent
f5451f7ff2
commit
1e70525bc9
1 changed files with 83 additions and 6 deletions
|
@ -194,6 +194,10 @@ gst_avf_video_source_device_type_get_type (void)
|
||||||
BOOL captureScreen;
|
BOOL captureScreen;
|
||||||
BOOL captureScreenCursor;
|
BOOL captureScreenCursor;
|
||||||
BOOL captureScreenMouseClicks;
|
BOOL captureScreenMouseClicks;
|
||||||
|
guint cropX;
|
||||||
|
guint cropY;
|
||||||
|
guint cropWidth;
|
||||||
|
guint cropHeight;
|
||||||
|
|
||||||
BOOL useVideoMeta;
|
BOOL useVideoMeta;
|
||||||
GstGLContextHelper *ctxh;
|
GstGLContextHelper *ctxh;
|
||||||
|
@ -214,6 +218,10 @@ gst_avf_video_source_device_type_get_type (void)
|
||||||
@property BOOL captureScreen;
|
@property BOOL captureScreen;
|
||||||
@property BOOL captureScreenCursor;
|
@property BOOL captureScreenCursor;
|
||||||
@property BOOL captureScreenMouseClicks;
|
@property BOOL captureScreenMouseClicks;
|
||||||
|
@property guint cropX;
|
||||||
|
@property guint cropY;
|
||||||
|
@property guint cropWidth;
|
||||||
|
@property guint cropHeight;
|
||||||
|
|
||||||
- (BOOL)openScreenInput;
|
- (BOOL)openScreenInput;
|
||||||
- (BOOL)openDeviceInput;
|
- (BOOL)openDeviceInput;
|
||||||
|
@ -294,7 +302,7 @@ static AVCaptureVideoOrientation GstAVFVideoSourceOrientation2AVCaptureVideoOrie
|
||||||
@implementation GstAVFVideoSrcImpl
|
@implementation GstAVFVideoSrcImpl
|
||||||
|
|
||||||
@synthesize deviceIndex, deviceName, position, orientation, deviceType, doStats,
|
@synthesize deviceIndex, deviceName, position, orientation, deviceType, doStats,
|
||||||
fps, captureScreen, captureScreenCursor, captureScreenMouseClicks;
|
fps, captureScreen, captureScreenCursor, captureScreenMouseClicks, cropX, cropY, cropWidth, cropHeight;
|
||||||
|
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
|
@ -393,6 +401,7 @@ static AVCaptureVideoOrientation GstAVFVideoSourceOrientation2AVCaptureVideoOrie
|
||||||
return NO;
|
return NO;
|
||||||
#else
|
#else
|
||||||
CGDirectDisplayID displayId;
|
CGDirectDisplayID displayId;
|
||||||
|
int screenHeight, screenWidth;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (element, "Opening screen input");
|
GST_DEBUG_OBJECT (element, "Opening screen input");
|
||||||
|
|
||||||
|
@ -403,7 +412,6 @@ static AVCaptureVideoOrientation GstAVFVideoSourceOrientation2AVCaptureVideoOrie
|
||||||
AVCaptureScreenInput *screenInput =
|
AVCaptureScreenInput *screenInput =
|
||||||
[[AVCaptureScreenInput alloc] initWithDisplayID:displayId];
|
[[AVCaptureScreenInput alloc] initWithDisplayID:displayId];
|
||||||
|
|
||||||
|
|
||||||
@try {
|
@try {
|
||||||
[screenInput setValue:[NSNumber numberWithBool:captureScreenCursor]
|
[screenInput setValue:[NSNumber numberWithBool:captureScreenCursor]
|
||||||
forKey:@"capturesCursor"];
|
forKey:@"capturesCursor"];
|
||||||
|
@ -415,6 +423,24 @@ static AVCaptureVideoOrientation GstAVFVideoSourceOrientation2AVCaptureVideoOrie
|
||||||
}
|
}
|
||||||
GST_WARNING ("Capturing cursor is only supported in OS X >= 10.8");
|
GST_WARNING ("Capturing cursor is only supported in OS X >= 10.8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screenHeight = CGDisplayPixelsHigh (displayId);
|
||||||
|
screenWidth = CGDisplayPixelsWide (displayId);
|
||||||
|
|
||||||
|
if (cropX + cropWidth > screenWidth || cropY + cropHeight > screenHeight) {
|
||||||
|
GST_WARNING ("Capture region outside of screen bounds, ignoring");
|
||||||
|
} else {
|
||||||
|
/* If width/height is not specified, assume max possible values */
|
||||||
|
int rectWidth = cropWidth ? cropWidth : (screenWidth - cropX);
|
||||||
|
int rectHeight = cropHeight ? cropHeight : (screenHeight - cropY);
|
||||||
|
|
||||||
|
/* cropRect (0,0) is bottom left, which feels counterintuitive.
|
||||||
|
* Make cropY relative to the top edge instead */
|
||||||
|
CGRect cropRect = CGRectMake (cropX, screenHeight - cropY - rectHeight,
|
||||||
|
rectWidth, rectHeight);
|
||||||
|
[screenInput setCropRect:cropRect];
|
||||||
|
}
|
||||||
|
|
||||||
screenInput.capturesMouseClicks = captureScreenMouseClicks;
|
screenInput.capturesMouseClicks = captureScreenMouseClicks;
|
||||||
input = screenInput;
|
input = screenInput;
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -771,7 +797,14 @@ checked:
|
||||||
|
|
||||||
if (captureScreen) {
|
if (captureScreen) {
|
||||||
#if !HAVE_IOS
|
#if !HAVE_IOS
|
||||||
CGRect rect = CGDisplayBounds ([self getDisplayIdFromDeviceIndex]);
|
CGRect rect;
|
||||||
|
AVCaptureScreenInput *screenInput = (AVCaptureScreenInput *)input;
|
||||||
|
if (CGRectIsEmpty (screenInput.cropRect)) {
|
||||||
|
rect = CGDisplayBounds ([self getDisplayIdFromDeviceIndex]);
|
||||||
|
} else {
|
||||||
|
rect = screenInput.cropRect;
|
||||||
|
}
|
||||||
|
|
||||||
float scale = [self getScaleFactorFromDeviceIndex];
|
float scale = [self getScaleFactorFromDeviceIndex];
|
||||||
for (NSNumber *pixel_format in pixel_formats) {
|
for (NSNumber *pixel_format in pixel_formats) {
|
||||||
GstVideoFormat gst_format = [self getGstVideoFormat:pixel_format];
|
GstVideoFormat gst_format = [self getGstVideoFormat:pixel_format];
|
||||||
|
@ -1244,6 +1277,10 @@ enum
|
||||||
PROP_CAPTURE_SCREEN,
|
PROP_CAPTURE_SCREEN,
|
||||||
PROP_CAPTURE_SCREEN_CURSOR,
|
PROP_CAPTURE_SCREEN_CURSOR,
|
||||||
PROP_CAPTURE_SCREEN_MOUSE_CLICKS,
|
PROP_CAPTURE_SCREEN_MOUSE_CLICKS,
|
||||||
|
PROP_CAPTURE_SCREEN_CROP_X,
|
||||||
|
PROP_CAPTURE_SCREEN_CROP_Y,
|
||||||
|
PROP_CAPTURE_SCREEN_CROP_WIDTH,
|
||||||
|
PROP_CAPTURE_SCREEN_CROP_HEIGHT,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1353,6 +1390,22 @@ gst_avf_video_src_class_init (GstAVFVideoSrcClass * klass)
|
||||||
g_param_spec_boolean ("capture-screen-mouse-clicks", "Enable mouse clicks capture",
|
g_param_spec_boolean ("capture-screen-mouse-clicks", "Enable mouse clicks capture",
|
||||||
"Enable mouse clicks capture while capturing screen", FALSE,
|
"Enable mouse clicks capture while capturing screen", FALSE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_CAPTURE_SCREEN_CROP_X,
|
||||||
|
g_param_spec_uint ("screen-crop-x", "Screen capture crop X",
|
||||||
|
"Horizontal coordinate of top left corner of the screen capture area",
|
||||||
|
0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_CAPTURE_SCREEN_CROP_Y,
|
||||||
|
g_param_spec_uint ("screen-crop-y", "Screen capture crop Y",
|
||||||
|
"Vertical coordinate of top left corner of the screen capture area",
|
||||||
|
0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_CAPTURE_SCREEN_CROP_WIDTH,
|
||||||
|
g_param_spec_uint ("screen-crop-width", "Screen capture crop width",
|
||||||
|
"Width of the screen capture area (0 = maximum)",
|
||||||
|
0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_CAPTURE_SCREEN_CROP_HEIGHT,
|
||||||
|
g_param_spec_uint ("screen-crop-height", "Screen capture crop height",
|
||||||
|
"Height of the screen capture area (0 = maximum)",
|
||||||
|
0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_avf_video_src_debug, "avfvideosrc",
|
GST_DEBUG_CATEGORY_INIT (gst_avf_video_src_debug, "avfvideosrc",
|
||||||
|
@ -1394,6 +1447,18 @@ gst_avf_video_src_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_CAPTURE_SCREEN_MOUSE_CLICKS:
|
case PROP_CAPTURE_SCREEN_MOUSE_CLICKS:
|
||||||
g_value_set_boolean (value, impl.captureScreenMouseClicks);
|
g_value_set_boolean (value, impl.captureScreenMouseClicks);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_X:
|
||||||
|
g_value_set_uint (value, impl.cropX);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_Y:
|
||||||
|
g_value_set_uint (value, impl.cropY);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_WIDTH:
|
||||||
|
g_value_set_uint (value, impl.cropWidth);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_HEIGHT:
|
||||||
|
g_value_set_uint (value, impl.cropHeight);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case PROP_DEVICE_INDEX:
|
case PROP_DEVICE_INDEX:
|
||||||
g_value_set_int (value, impl.deviceIndex);
|
g_value_set_int (value, impl.deviceIndex);
|
||||||
|
@ -1402,13 +1467,13 @@ gst_avf_video_src_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
g_value_set_string (value, impl.deviceName);
|
g_value_set_string (value, impl.deviceName);
|
||||||
break;
|
break;
|
||||||
case PROP_POSITION:
|
case PROP_POSITION:
|
||||||
g_value_set_enum(value, impl.position);
|
g_value_set_enum (value, impl.position);
|
||||||
break;
|
break;
|
||||||
case PROP_ORIENTATION:
|
case PROP_ORIENTATION:
|
||||||
g_value_set_enum(value, impl.orientation);
|
g_value_set_enum (value, impl.orientation);
|
||||||
break;
|
break;
|
||||||
case PROP_DEVICE_TYPE:
|
case PROP_DEVICE_TYPE:
|
||||||
g_value_set_enum(value, impl.deviceType);
|
g_value_set_enum (value, impl.deviceType);
|
||||||
break;
|
break;
|
||||||
case PROP_DO_STATS:
|
case PROP_DO_STATS:
|
||||||
g_value_set_boolean (value, impl.doStats);
|
g_value_set_boolean (value, impl.doStats);
|
||||||
|
@ -1441,6 +1506,18 @@ gst_avf_video_src_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_CAPTURE_SCREEN_MOUSE_CLICKS:
|
case PROP_CAPTURE_SCREEN_MOUSE_CLICKS:
|
||||||
impl.captureScreenMouseClicks = g_value_get_boolean (value);
|
impl.captureScreenMouseClicks = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_X:
|
||||||
|
impl.cropX = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_Y:
|
||||||
|
impl.cropY = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_WIDTH:
|
||||||
|
impl.cropWidth = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_CAPTURE_SCREEN_CROP_HEIGHT:
|
||||||
|
impl.cropHeight = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case PROP_DEVICE_INDEX:
|
case PROP_DEVICE_INDEX:
|
||||||
impl.deviceIndex = g_value_get_int (value);
|
impl.deviceIndex = g_value_get_int (value);
|
||||||
|
|
Loading…
Reference in a new issue