예제 #1
0
파일: mac.c 프로젝트: Mettbrot/vlc
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;
}
예제 #2
0
파일: mac.c 프로젝트: CSRedRat/vlc
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;
}