Commit d882b56e authored by Felix Paul Kühne's avatar Felix Paul Kühne

screen: added error handling to prevent this module from failing silently

parent 921123fd
...@@ -87,27 +87,42 @@ int screen_InitCapture( demux_t *p_demux ) ...@@ -87,27 +87,42 @@ int screen_InitCapture( demux_t *p_demux )
CGLPixelFormatObj pix; CGLPixelFormatObj pix;
GLint npix; GLint npix;
GLint viewport[4]; GLint viewport[4];
GLuint displayMask;
CGLError returnedError;
p_sys->p_data = p_data = p_sys->p_data = p_data =
( screen_data_t * )malloc( sizeof( screen_data_t ) ); ( screen_data_t * )malloc( sizeof( screen_data_t ) );
attribs[0] = kCGLPFAFullScreen; attribs[0] = kCGLPFAFullScreen;
attribs[1] = kCGLPFADisplayMask; attribs[1] = kCGLPFADisplayMask;
attribs[2] = CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ); attribs[2] = CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() );
attribs[3] = 0; attribs[3] = 0;
CGLChoosePixelFormat( attribs, &pix, &npix );
CGLCreateContext( pix, NULL, &( p_data->screen ) );
CGLDestroyPixelFormat( pix );
CGLSetCurrentContext( p_data->screen ); returnedError = CGLChoosePixelFormat( attribs, &pix, &npix );
CGLSetFullScreen( p_data->screen ); 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 ); glGetIntegerv( GL_VIEWPORT, viewport );
p_data->screen_width = viewport[2]; p_data->screen_width = viewport[2];
p_data->screen_height = viewport[3]; p_data->screen_height = viewport[3];
p_data->left = p_sys->i_left; p_data->left = p_sys->i_left;
p_data->top = p_sys->i_top; p_data->top = p_sys->i_top;
p_data->src_width = var_CreateGetInteger( p_demux, "screen-width" ); p_data->src_width = var_CreateGetInteger( p_demux, "screen-width" );
...@@ -118,36 +133,49 @@ int screen_InitCapture( demux_t *p_demux ) ...@@ -118,36 +133,49 @@ int screen_InitCapture( demux_t *p_demux )
} }
p_data->dest_width = p_data->src_width; p_data->dest_width = p_data->src_width;
p_data->dest_height = p_data->src_height; p_data->dest_height = p_data->src_height;
attribs [0] = kCGLPFAOffScreen; attribs [0] = kCGLPFAOffScreen;
attribs [1] = kCGLPFAColorSize; attribs [1] = kCGLPFAColorSize;
attribs [2] = 32; attribs [2] = 32;
attribs [3] = 0; attribs [3] = 0;
CGLChoosePixelFormat( attribs, &pix, &npix );
CGLCreateContext( pix, NULL, &( p_data->scaled ) );
CGLDestroyPixelFormat( pix );
CGLSetCurrentContext( p_data->scaled ); 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->scaled_image = ( char * )malloc( p_data->dest_width
* p_data->dest_height * 4 ); * p_data->dest_height * 4 );
CGLSetOffScreen( p_data->scaled, p_data->dest_width, p_data->dest_height, #warning FIXME: CGLSetOffScreen is no longer supported in the future!
p_data->dest_width * 4, p_data->scaled_image ); 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 ); 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_* must set to screen size, not subscreen size */
p_sys->fmt.video.i_width = p_data->screen_width; 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_visible_width = p_data->screen_width;
p_sys->fmt.video.i_height = p_data->screen_height; p_sys->fmt.video.i_height = p_data->screen_height;
p_sys->fmt.video.i_bits_per_pixel = 32; p_sys->fmt.video.i_bits_per_pixel = 32;
glGenTextures( 1, &( p_data->texture ) ); glGenTextures( 1, &( p_data->texture ) );
glBindTexture( GL_TEXTURE_2D, p_data->texture ); glBindTexture( GL_TEXTURE_2D, p_data->texture );
p_data->texture_image p_data->texture_image
= ( char * )malloc( p_data->src_width * p_data->src_height * 4 ); = ( 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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP );
...@@ -155,27 +183,31 @@ int screen_InitCapture( demux_t *p_demux ) ...@@ -155,27 +183,31 @@ int screen_InitCapture( demux_t *p_demux )
glGenTextures( 1, &( p_data->cursor_texture ) ); glGenTextures( 1, &( p_data->cursor_texture ) );
glBindTexture( GL_TEXTURE_2D, 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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
CGSNewConnection( NULL, &( p_data->connection ) ); CGSNewConnection( NULL, &( p_data->connection ) );
return VLC_SUCCESS; return VLC_SUCCESS;
errorHandling:
msg_Err( p_demux, "Core OpenGL failure: %s", CGLErrorString( returnedError ) );
return VLC_EGENERIC;
} }
int screen_CloseCapture( demux_t *p_demux ) int screen_CloseCapture( demux_t *p_demux )
{ {
screen_data_t *p_data = ( screen_data_t * )p_demux->p_sys->p_data; screen_data_t *p_data = ( screen_data_t * )p_demux->p_sys->p_data;
CGSReleaseConnection( p_data->connection ); CGSReleaseConnection( p_data->connection );
CGLSetCurrentContext( NULL ); CGLSetCurrentContext( NULL );
CGLClearDrawable( p_data->screen ); CGLClearDrawable( p_data->screen );
CGLDestroyContext( p_data->screen ); CGLDestroyContext( p_data->screen );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -185,24 +217,24 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -185,24 +217,24 @@ block_t *screen_Capture( demux_t *p_demux )
screen_data_t *p_data = ( screen_data_t * )p_sys->p_data; screen_data_t *p_data = ( screen_data_t * )p_sys->p_data;
block_t *p_block; block_t *p_block;
int i_size; int i_size;
i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 4; i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 4;
if( !( p_block = block_New( p_demux, i_size ) ) ) if( !( p_block = block_New( p_demux, i_size ) ) )
{ {
msg_Warn( p_demux, "cannot get block" ); msg_Warn( p_demux, "cannot get block" );
return NULL; return NULL;
} }
CGPoint cursor_pos; CGPoint cursor_pos;
CGError cursor_result; CGError cursor_result;
cursor_pos.x = 0; cursor_pos.x = 0;
cursor_pos.y = 0; cursor_pos.y = 0;
cursor_result cursor_result
= CGSGetCurrentCursorLocation( p_data->connection, &cursor_pos ); = CGSGetCurrentCursorLocation( p_data->connection, &cursor_pos );
if( p_sys->b_follow_mouse if( p_sys->b_follow_mouse
&& cursor_result == kCGErrorSuccess ) && cursor_result == kCGErrorSuccess )
{ {
...@@ -210,7 +242,7 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -210,7 +242,7 @@ block_t *screen_Capture( demux_t *p_demux )
p_data->left = p_sys->i_left; p_data->left = p_sys->i_left;
p_data->top = p_sys->i_top; p_data->top = p_sys->i_top;
} }
CGLSetCurrentContext( p_data->screen ); CGLSetCurrentContext( p_data->screen );
glReadPixels( p_data->left, glReadPixels( p_data->left,
p_data->screen_height - p_data->top - p_data->src_height, p_data->screen_height - p_data->top - p_data->src_height,
...@@ -218,14 +250,14 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -218,14 +250,14 @@ block_t *screen_Capture( demux_t *p_demux )
p_data->src_height, p_data->src_height,
GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE,
p_data->texture_image ); p_data->texture_image );
CGLSetCurrentContext( p_data->scaled ); CGLSetCurrentContext( p_data->scaled );
glEnable( GL_TEXTURE_2D ); glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, p_data->texture ); glBindTexture( GL_TEXTURE_2D, p_data->texture );
glTexImage2D( GL_TEXTURE_2D, 0, glTexImage2D( GL_TEXTURE_2D, 0,
GL_RGBA8, p_data->src_width, p_data->src_height, 0, GL_RGBA8, p_data->src_width, p_data->src_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, p_data->texture_image ); GL_RGBA, GL_UNSIGNED_BYTE, p_data->texture_image );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT );
glColor3f( 1.0f, 1.0f, 1.0f ); glColor3f( 1.0f, 1.0f, 1.0f );
...@@ -238,13 +270,13 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -238,13 +270,13 @@ block_t *screen_Capture( demux_t *p_demux )
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, 1.0 );
glEnd(); glEnd();
glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_2D );
int size; int size;
int tmp1, tmp2, tmp3, tmp4; int tmp1, tmp2, tmp3, tmp4;
unsigned char *cursor_image; unsigned char *cursor_image;
CGRect cursor_rect; CGRect cursor_rect;
CGPoint cursor_hot; CGPoint cursor_hot;
if( cursor_result == kCGErrorSuccess if( cursor_result == kCGErrorSuccess
&& CGSGetGlobalCursorDataSize( p_data->connection, &size ) && CGSGetGlobalCursorDataSize( p_data->connection, &size )
== kCGErrorSuccess ) == kCGErrorSuccess )
...@@ -265,10 +297,10 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -265,10 +297,10 @@ block_t *screen_Capture( demux_t *p_demux )
( int )( cursor_rect.size.height ), 0, ( int )( cursor_rect.size.height ), 0,
GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, GL_UNSIGNED_BYTE,
( char * )cursor_image ); ( char * )cursor_image );
cursor_rect.origin.x = cursor_pos.x - p_data->left - cursor_hot.x; cursor_rect.origin.x = cursor_pos.x - p_data->left - cursor_hot.x;
cursor_rect.origin.y = cursor_pos.y - p_data->top - cursor_hot.y; cursor_rect.origin.y = cursor_pos.y - p_data->top - cursor_hot.y;
cursor_rect.origin.x cursor_rect.origin.x
= 2.0 * cursor_rect.origin.x / p_data->src_width - 1.0; = 2.0 * cursor_rect.origin.x / p_data->src_width - 1.0;
cursor_rect.origin.y cursor_rect.origin.y
...@@ -277,7 +309,7 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -277,7 +309,7 @@ block_t *screen_Capture( demux_t *p_demux )
= 2.0 * cursor_rect.size.width / p_data->src_width; = 2.0 * cursor_rect.size.width / p_data->src_width;
cursor_rect.size.height cursor_rect.size.height
= 2.0 * cursor_rect.size.height / p_data->src_height; = 2.0 * cursor_rect.size.height / p_data->src_height;
glColor3f( 1.0f, 1.0f, 1.0f ); glColor3f( 1.0f, 1.0f, 1.0f );
glEnable( GL_TEXTURE_2D ); glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND ); glEnable( GL_BLEND );
...@@ -302,12 +334,12 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -302,12 +334,12 @@ block_t *screen_Capture( demux_t *p_demux )
} }
free( cursor_image ); free( cursor_image );
} }
glReadPixels( 0, 0, glReadPixels( 0, 0,
p_data->dest_width, p_data->dest_width,
p_data->dest_height, p_data->dest_height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
p_block->p_buffer ); p_block->p_buffer );
return p_block; return p_block;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment