[vlc-commits] screen/mac: cursor rendering
arai
git at videolan.org
Tue Feb 26 23:02:31 CET 2013
vlc | branch: master | arai <arai_a at mac.com> | Tue Feb 26 21:28:41 2013 +0900| [3f39f4163498762a6b45cef1cb44658b7813ade4] | committer: Felix Paul Kühne
screen/mac: cursor rendering
Signed-off-by: Felix Paul Kühne <fkuehne at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3f39f4163498762a6b45cef1cb44658b7813ade4
---
modules/access/screen/mac.c | 146 +++++++++++++++++++++----------------------
1 file changed, 71 insertions(+), 75 deletions(-)
diff --git a/modules/access/screen/mac.c b/modules/access/screen/mac.c
index 09dd7b1..698e362 100644
--- a/modules/access/screen/mac.c
+++ b/modules/access/screen/mac.c
@@ -56,6 +56,11 @@ struct screen_data_t
int screen_height;
CGDirectDisplayID display_id;
+
+ CGContextRef offscreen_context;
+ CGRect offscreen_rect;
+ void *offscreen_bitmap;
+ size_t offscreen_bitmap_size;
};
int screen_InitCapture(demux_t *p_demux)
@@ -63,7 +68,6 @@ int screen_InitCapture(demux_t *p_demux)
demux_sys_t *p_sys = p_demux->p_sys;
screen_data_t *p_data;
CGLError returnedError;
- int i_bits_per_pixel, i_chroma = 0;
p_sys->p_data = p_data = calloc(1, sizeof(screen_data_t));
if (!p_data)
@@ -106,59 +110,17 @@ int screen_InitCapture(demux_t *p_demux)
p_data->height = p_data->screen_height;
}
- CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(CGDisplayCopyDisplayMode(p_data->display_id));
- int length = CFStringGetLength(pixelEncoding);
- length++;
- char *psz_name = (char *)malloc(length);
- CFStringGetCString(pixelEncoding, psz_name, length, kCFStringEncodingUTF8);
- msg_Dbg(p_demux, "pixel encoding is '%s'", psz_name);
- CFRelease(pixelEncoding);
-
- if (!strcmp(psz_name, IO32BitDirectPixels)) {
- i_chroma = VLC_CODEC_RGB32;
- i_bits_per_pixel = 32;
- } else if (!strcmp(psz_name, IO16BitDirectPixels)) {
- i_chroma = VLC_CODEC_RGB16;
- i_bits_per_pixel = 16;
- } else if (!strcmp(psz_name, IO8BitIndexedPixels)) {
- i_chroma = VLC_CODEC_RGB8;
- i_bits_per_pixel = 8;
- } else {
- msg_Err(p_demux, "unsupported pixel encoding");
- free(p_data);
- return VLC_EGENERIC;
- }
- free(psz_name);
-
/* setup format */
- es_format_Init(&p_sys->fmt, VIDEO_ES, i_chroma);
+ es_format_Init(&p_sys->fmt, VIDEO_ES, VLC_CODEC_RGB32);
p_sys->fmt.video.i_visible_width =
p_sys->fmt.video.i_width = rect.size.width;
p_sys->fmt.video.i_visible_height =
p_sys->fmt.video.i_height = rect.size.height;
- p_sys->fmt.video.i_bits_per_pixel = i_bits_per_pixel;
- p_sys->fmt.video.i_chroma = i_chroma;
-
- switch (i_chroma) {
- case VLC_CODEC_RGB15:
- p_sys->fmt.video.i_rmask = 0x7c00;
- p_sys->fmt.video.i_gmask = 0x03e0;
- p_sys->fmt.video.i_bmask = 0x001f;
- break;
- case VLC_CODEC_RGB24:
- p_sys->fmt.video.i_rmask = 0x00ff0000;
- p_sys->fmt.video.i_gmask = 0x0000ff00;
- p_sys->fmt.video.i_bmask = 0x000000ff;
- break;
- case VLC_CODEC_RGB32:
- p_sys->fmt.video.i_rmask = 0x00ff0000;
- p_sys->fmt.video.i_gmask = 0x0000ff00;
- p_sys->fmt.video.i_bmask = 0x000000ff;
- break;
- default:
- msg_Warn( p_demux, "Unknown RGB masks" );
- break;
- }
+ p_sys->fmt.video.i_bits_per_pixel = 32;
+ p_sys->fmt.video.i_chroma = VLC_CODEC_RGB32;
+ p_sys->fmt.video.i_rmask = 0x00ff0000;
+ p_sys->fmt.video.i_gmask = 0x0000ff00;
+ p_sys->fmt.video.i_bmask = 0x000000ff;
return VLC_SUCCESS;
}
@@ -168,6 +130,12 @@ int screen_CloseCapture(demux_t *p_demux)
demux_sys_t *p_sys = p_demux->p_sys;
screen_data_t *p_data = p_sys->p_data;
+ if (p_data->offscreen_context)
+ CFRelease(p_data->offscreen_context);
+
+ if (p_data->offscreen_bitmap)
+ free(p_data->offscreen_bitmap);
+
if (p_data->p_block)
block_Release(p_data->p_block);
@@ -183,8 +151,6 @@ block_t *screen_Capture(demux_t *p_demux)
block_t *p_block;
CGRect capture_rect;
CGImageRef image;
- CGDataProviderRef dataProvider;
- CFDataRef data;
/* forward cursor location */
CGPoint cursor_pos;
@@ -204,37 +170,67 @@ block_t *screen_Capture(demux_t *p_demux)
capture_rect.size.width = p_data->width;
capture_rect.size.height = p_data->height;
-#if 0
- // FIXME: actually plot cursor image into snapshot
- /* fetch cursor image */
- CGImageRef cursor_image;
- int cid = CGSMainConnectionID();
- CGPoint outHotSpot;
- cursor_image = CGSCreateRegisteredCursorImage(cid, (char *)"com.apple.coregraphics.GlobalCurrent", &outHotSpot);
-#endif
-
/* fetch image data */
image = CGDisplayCreateImageForRect(p_data->display_id, capture_rect);
- if (image) {
- /* build block */
- int i_buffer = (p_sys->fmt.video.i_bits_per_pixel + 7) / 8 * p_sys->fmt.video.i_width * p_sys->fmt.video.i_height;
- p_block = block_Alloc(i_buffer);
- if (!p_block) {
- msg_Warn(p_demux, "can't get block");
+ if (!image) {
+ msg_Warn(p_demux, "no image!");
+ return NULL;
+ }
+
+ /* create offscreen context */
+ if (!p_data->offscreen_context) {
+ CGColorSpaceRef colorspace;
+
+ colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+
+ p_data->offscreen_bitmap_size = p_sys->fmt.video.i_width * p_sys->fmt.video.i_height * 4;
+ p_data->offscreen_bitmap = calloc(1, p_data->offscreen_bitmap_size);
+ if (p_data->offscreen_bitmap == NULL) {
+ msg_Warn(p_demux, "can't allocate offscreen bitmap");
+ CFRelease(image);
return NULL;
}
- dataProvider = CGImageGetDataProvider(image);
- data = CGDataProviderCopyData(dataProvider);
- CFDataGetBytes(data, CFRangeMake(0,CFDataGetLength(data)), p_block->p_buffer);
+ p_data->offscreen_context = CGBitmapContextCreate(p_data->offscreen_bitmap, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height, 8, p_sys->fmt.video.i_width * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
+ if (!p_data->offscreen_context) {
+ msg_Warn(p_demux, "can't create offscreen bitmap context");
+ CFRelease(image);
+ return NULL;
+ }
- CFRelease(data);
- CFRelease(dataProvider);
- CFRelease(image);
+ CGColorSpaceRelease(colorspace);
- return p_block;
+ p_data->offscreen_rect = CGRectMake(0, 0, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height);
}
- msg_Warn(p_demux, "no image!");
- return NULL;
+ /* fetch cursor image */
+ CGImageRef cursor_image;
+ int cid = CGSMainConnectionID();
+ CGPoint outHotSpot;
+ cursor_image = CGSCreateRegisteredCursorImage(cid, (char *)"com.apple.coregraphics.GlobalCurrent", &outHotSpot);
+
+ /* draw screen image and cursor image */
+ CGRect cursor_rect;
+ cursor_rect.size.width = CGImageGetWidth(cursor_image);
+ cursor_rect.size.height = CGImageGetHeight(cursor_image);
+ cursor_rect.origin.x = cursor_pos.x - p_sys->i_left - outHotSpot.x;
+ cursor_rect.origin.y = p_data->offscreen_rect.size.height
+ - (cursor_pos.y + cursor_rect.size.height - p_sys->i_top - outHotSpot.y);
+
+ CGContextDrawImage(p_data->offscreen_context, p_data->offscreen_rect, image);
+ CGContextDrawImage(p_data->offscreen_context, cursor_rect, cursor_image);
+
+ /* build block */
+ p_block = block_Alloc(p_data->offscreen_bitmap_size);
+ if (!p_block) {
+ msg_Warn(p_demux, "can't get block");
+ CFRelease(image);
+ return NULL;
+ }
+
+ memmove(p_block->p_buffer, p_data->offscreen_bitmap, p_data->offscreen_bitmap_size);
+
+ CFRelease(image);
+
+ return p_block;
}
More information about the vlc-commits
mailing list