int screen_InitCapture( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; screen_data_t *p_data; CGLError returnedError; unsigned int i; p_sys->p_data = p_data = ( screen_data_t * )calloc( 1, sizeof( screen_data_t ) ); p_data->display_id = kCGDirectMainDisplay; unsigned int displayCount; displayCount = 0; returnedError = CGGetOnlineDisplayList( 0, NULL, &displayCount ); if( !returnedError ) { CGDirectDisplayID *ids; ids = ( CGDirectDisplayID * )malloc( displayCount * sizeof( CGDirectDisplayID ) ); returnedError = CGGetOnlineDisplayList( displayCount, ids, &displayCount ); if( !returnedError ) { if ( p_sys->i_display_id > 0 ) { for( i = 0; i < displayCount; i ++ ) { if( p_sys->i_display_id == ids[i] ) { p_data->display_id = ids[i]; break; } } } else if ( p_sys->i_screen_index > 0 && p_sys->i_screen_index <= displayCount ) { p_data->display_id = ids[p_sys->i_screen_index - 1]; } } free( ids ); } /* CGImage Function * CGDisplayCreateImageForRect is available in Mac OS X v10.6 and later */ p_data->myCGDisplayCreateImageForRect = NULL; CFURLRef frameworkURL = NULL; CFStringRef path = CFSTR( "file://localhost/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework" ); frameworkURL = CFURLCreateWithString( kCFAllocatorDefault, path, NULL ); if( frameworkURL != NULL ) { p_data->bundle = CFBundleCreate( kCFAllocatorDefault, frameworkURL ); if( p_data->bundle != NULL ) { p_data->myCGDisplayCreateImageForRect = ( typeofCGDisplayCreateImageForRect )CFBundleGetFunctionPointerForName ( p_data->bundle, CFSTR( "CGDisplayCreateImageForRect" ) ); } CFRelease( frameworkURL ); } /* Screen Size */ CGRect rect = CGDisplayBounds( p_data->display_id ); p_data->screen_left = rect.origin.x; p_data->screen_top = rect.origin.y; p_data->screen_width = rect.size.width; p_data->screen_height = rect.size.height; p_data->width = p_sys->i_width; p_data->height = p_sys->i_height; if( p_data->width <= 0 || p_data->height <= 0 ) { p_data->width = p_data->screen_width; p_data->height = p_data->screen_height; } /* Screen Context */ if( p_data->myCGDisplayCreateImageForRect == NULL ) { returnedError = screen_CreateContext( &p_data->screen, kCGLPFAFullScreen, kCGLPFADisplayMask, ( CGLPixelFormatAttribute )CGDisplayIDToOpenGLDisplayMask( p_data->display_id ), ( CGLPixelFormatAttribute )0 ); if( returnedError ) goto errorHandling; returnedError = CGLSetCurrentContext( p_data->screen ); if( returnedError ) goto errorHandling; returnedError = CGLSetFullScreen( p_data->screen ); if( returnedError ) goto errorHandling; } /* Clipped Context */ returnedError = screen_CreateContext( &p_data->clipped, kCGLPFAOffScreen, kCGLPFAColorSize, ( CGLPixelFormatAttribute )32, ( CGLPixelFormatAttribute )0 ); if( returnedError ) goto errorHandling; returnedError = CGLSetCurrentContext( p_data->clipped ); if( returnedError ) goto errorHandling; /* Clipped Image */ p_data->clipped_image = ( char * )malloc( p_data->width * p_data->height * 4 ); returnedError = CGLSetOffScreen( p_data->clipped, p_data->width, p_data->height, p_data->width * 4, p_data->clipped_image ); if( returnedError ) goto errorHandling; /* Screen Image */ if( p_data->myCGDisplayCreateImageForRect != NULL ) { p_data->screen_image = ( char * )malloc( p_data->screen_width * p_data->screen_height * 4 ); } else { p_data->screen_image = ( char * )malloc( p_data->width * p_data->height * 4 ); } /* Cursor */ CGSNewConnection( NULL, &( p_data->connection ) ); p_data->cursor_need_update = 1; p_data->cursor_seed = 0; glGenTextures( 1, &( p_data->cursor_texture ) ); glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); /* System */ es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_RGB32 ); /* p_sys->fmt.video.i_* must set to screen size, not subscreen size */ p_sys->fmt.video.i_width = p_data->screen_width; p_sys->fmt.video.i_visible_width = p_data->screen_width; p_sys->fmt.video.i_height = p_data->screen_height; p_sys->fmt.video.i_bits_per_pixel = 32; return VLC_SUCCESS; errorHandling: msg_Err( p_demux, "Core OpenGL failure: %s", CGLErrorString( returnedError ) ); return VLC_EGENERIC; }
int screen_InitCapture( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; screen_data_t *p_data; CGLPixelFormatAttribute attribs[4]; CGLPixelFormatObj pix; GLint npix; GLint viewport[4]; GLuint displayMask; CGLError returnedError; p_sys->p_data = p_data = ( screen_data_t * )malloc( sizeof( screen_data_t ) ); attribs[0] = kCGLPFAFullScreen; attribs[1] = kCGLPFADisplayMask; attribs[2] = CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ); attribs[3] = 0; returnedError = CGLChoosePixelFormat( attribs, &pix, &npix ); if (returnedError) goto errorHandling; returnedError = CGLCreateContext( pix, NULL, &( p_data->screen ) ); if (returnedError) goto errorHandling; returnedError = CGLDestroyPixelFormat( pix ); if (returnedError) goto errorHandling; returnedError = CGLSetCurrentContext( p_data->screen ); if (returnedError) goto errorHandling; returnedError = CGLSetFullScreen( p_data->screen ); if (returnedError) goto errorHandling; glGetIntegerv( GL_VIEWPORT, viewport ); p_data->screen_width = viewport[2]; p_data->screen_height = viewport[3]; p_data->left = p_sys->i_left; p_data->top = p_sys->i_top; p_data->src_width = var_CreateGetInteger( p_demux, "screen-width" ); p_data->src_height = var_CreateGetInteger( p_demux, "screen-height" ); if (p_data->src_width <= 0 || p_data->src_height <= 0) { p_data->src_width = p_data->screen_width; p_data->src_height = p_data->screen_height; } p_data->dest_width = p_data->src_width; p_data->dest_height = p_data->src_height; attribs [0] = kCGLPFAOffScreen; attribs [1] = kCGLPFAColorSize; attribs [2] = 32; attribs [3] = 0; returnedError = CGLChoosePixelFormat( attribs, &pix, &npix ); if (returnedError) goto errorHandling; returnedError = CGLCreateContext( pix, NULL, &( p_data->scaled ) ); if (returnedError) goto errorHandling; returnedError = CGLDestroyPixelFormat( pix ); if (returnedError) goto errorHandling; returnedError = CGLSetCurrentContext( p_data->scaled ); if (returnedError) goto errorHandling; p_data->scaled_image = ( char * )malloc( p_data->dest_width * p_data->dest_height * 4 ); #warning FIXME: CGLSetOffScreen is no longer supported in the future! returnedError = CGLSetOffScreen( p_data->scaled, p_data->dest_width, p_data->dest_height, p_data->dest_width * 4, p_data->scaled_image ); if (returnedError) goto errorHandling; es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_RGB32 ); /* p_sys->fmt.video.i_* must set to screen size, not subscreen size */ p_sys->fmt.video.i_width = p_data->screen_width; p_sys->fmt.video.i_visible_width = p_data->screen_width; p_sys->fmt.video.i_height = p_data->screen_height; p_sys->fmt.video.i_bits_per_pixel = 32; glGenTextures( 1, &( p_data->texture ) ); glBindTexture( GL_TEXTURE_2D, p_data->texture ); p_data->texture_image = ( char * )malloc( p_data->src_width * p_data->src_height * 4 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glGenTextures( 1, &( p_data->cursor_texture ) ); glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); CGSNewConnection( NULL, &( p_data->connection ) ); return VLC_SUCCESS; errorHandling: msg_Err( p_demux, "Core OpenGL failure: %s", CGLErrorString( returnedError ) ); return VLC_EGENERIC; }