vout.m

来自「VLC媒体播放程序」· M 代码 · 共 1,859 行 · 第 1/4 页

M
1,859
字号
        f_x = 1.0;        f_y = 1.0;    }    else if( bounds.size.height * p_vout->output.i_aspect <        bounds.size.width * VOUT_ASPECT_FACTOR )    {        f_x = bounds.size.height * p_vout->output.i_aspect /            VOUT_ASPECT_FACTOR / bounds.size.width;        f_y = 1.0;    }    else    {        f_x = 1.0;        f_y = bounds.size.width * VOUT_ASPECT_FACTOR /            p_vout->output.i_aspect / bounds.size.height;    }}- (void) initTextures{    [currentContext makeCurrentContext];    /* Free previous texture if any */    if( i_texture )    {        glDeleteTextures( 1, &i_texture );    }        /* Create textures */    glGenTextures( 1, &i_texture );    glEnable( GL_TEXTURE_RECTANGLE_EXT );    glEnable( GL_UNPACK_CLIENT_STORAGE_APPLE );    glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );    /* Use VRAM texturing */    glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,            GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE );    /* Tell the driver not to make a copy of the texture but to use       our buffer */    glPixelStorei( GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE );    /* Linear interpolation */    glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,            GL_TEXTURE_MIN_FILTER, GL_LINEAR );    glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,            GL_TEXTURE_MAG_FILTER, GL_LINEAR );    /* I have no idea what this exactly does, but it seems to be       necessary for scaling */    glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,            GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );    glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,            GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );    glTexImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,            p_vout->output.i_width, p_vout->output.i_height, 0,            GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,            PP_OUTPUTPICTURE[0]->p_data );    initDone = 1;}- (void) reloadTexture{    if( !initDone )    {        return;    }        [currentContext makeCurrentContext];    glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );    /* glTexSubImage2D is faster than glTexImage2D       http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/       TextureRange/MainOpenGLView.m.htm */    glTexSubImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0,            p_vout->output.i_width, p_vout->output.i_height,            GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,            PP_OUTPUTPICTURE[0]->p_data );}- (void) goFullScreen{    /* Create the new pixel format */    NSOpenGLPixelFormatAttribute attribs[] =    {        NSOpenGLPFAAccelerated,        NSOpenGLPFANoRecovery,        NSOpenGLPFADoubleBuffer,        NSOpenGLPFAColorSize, 24,        NSOpenGLPFAAlphaSize, 8,        NSOpenGLPFADepthSize, 24,        NSOpenGLPFAFullScreen,        NSOpenGLPFAScreenMask,        /* TODO handle macosxx-vdev */        CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ),        0    };    NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]        initWithAttributes: attribs];    if( !fmt )    {        msg_Warn( p_vout, "Cannot create NSOpenGLPixelFormat" );        return;    }    /* Create the new OpenGL context */    fullScreenContext = [[NSOpenGLContext alloc]        initWithFormat: fmt shareContext: nil];    if( !fullScreenContext )    {        msg_Warn( p_vout, "Failed to create new NSOpenGLContext" );        return;    }    currentContext = fullScreenContext;    /* Capture display, switch to fullscreen */    if( CGCaptureAllDisplays() != CGDisplayNoErr )    {        msg_Warn( p_vout, "CGCaptureAllDisplays() failed" );        return;    }    [fullScreenContext setFullScreen];    [fullScreenContext makeCurrentContext];    /* Fix ratio */    unsigned width  = CGDisplayPixelsWide( kCGDirectMainDisplay );    unsigned height = CGDisplayPixelsHigh( kCGDirectMainDisplay );    if( config_GetInt( p_vout, "macosx-stretch" ) )    {        f_x = 1.0;        f_y = 1.0;    }    else if( height * p_vout->output.i_aspect <                 width * VOUT_ASPECT_FACTOR )    {        f_x = (float) height * p_vout->output.i_aspect /            width / VOUT_ASPECT_FACTOR;        f_y = 1.0;    }    else    {        f_x = 1.0;        f_y = (float) width * VOUT_ASPECT_FACTOR /        p_vout->output.i_aspect / height;    }    /* Update viewport, re-init textures */    glViewport( 0, 0, width, height );    [self initTextures];    /* Redraw the last picture */    [self setNeedsDisplay: YES];    isFullScreen = 1;}- (void) exitFullScreen{    /* Free current OpenGL context */    [NSOpenGLContext clearCurrentContext];    [fullScreenContext clearDrawable];    [fullScreenContext release];    CGReleaseAllDisplays();    currentContext = [self openGLContext];    [self initTextures];    [self reshape];    /* Redraw the last picture */    [self setNeedsDisplay: YES];    isFullScreen = 0;}- (void) cleanUp{    if( isFullScreen )    {        [self exitFullScreen];    }    initDone = 0;}- (void) drawQuad{    glBegin( GL_QUADS );        /* Top left */        glTexCoord2f( 0.0, 0.0 );        glVertex2f( - f_x, f_y );        /* Bottom left */        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex2f( - f_x, - f_y );        /* Bottom right */        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex2f( f_x, - f_y );        /* Top right */        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex2f( f_x, f_y );    glEnd();}- (void) drawCube{    glBegin( GL_QUADS );        /* Front */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( - 1.0, 1.0, 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( - 1.0, - 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( 1.0, - 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( 1.0, 1.0, 1.0 );        /* Left */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( - 1.0, 1.0, - 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( - 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( - 1.0, - 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( - 1.0, 1.0, 1.0 );        /* Back */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( 1.0, 1.0, - 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( - 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( - 1.0, 1.0, - 1.0 );        /* Right */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( 1.0, 1.0, 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( 1.0, - 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( 1.0, 1.0, - 1.0 );        /* Top */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( - 1.0, 1.0, - 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( - 1.0, 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( 1.0, 1.0, 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( 1.0, 1.0, - 1.0 );        /* Bottom */        glTexCoord2f( 0.0, 0.0 );        glVertex3f( - 1.0, - 1.0, 1.0 );        glTexCoord2f( 0.0, (float) p_vout->output.i_height );        glVertex3f( - 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width,                      (float) p_vout->output.i_height );        glVertex3f( 1.0, - 1.0, - 1.0 );        glTexCoord2f( (float) p_vout->output.i_width, 0.0 );        glVertex3f( 1.0, - 1.0, 1.0 );    glEnd();}- (void) drawRect: (NSRect) rect{    [currentContext makeCurrentContext];    /* Swap buffers only during the vertical retrace of the monitor.       http://developer.apple.com/documentation/GraphicsImaging/       Conceptual/OpenGL/chap5/chapter_5_section_44.html */    long params[] = { 1 };    CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,                     params );        /* Black background */    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );    if( !initDone )    {        [currentContext flushBuffer];        return;    }    /* Draw */    glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );    if( i_effect & ( OPENGL_EFFECT_CUBE |                OPENGL_EFFECT_TRANSPARENT_CUBE ) )    {        glRotatef( 1.0, 0.3, 0.5, 0.7 );        [self drawCube];    }    else    {        [self drawQuad];    }    /* Wait for the job to be done */    [currentContext flushBuffer];}@end/***************************************************************************** * VLCVout implementation *****************************************************************************/@implementation VLCVout- (void)createWindow:(NSValue *)o_value{    vlc_value_t val;    VLCQTView * o_view;    NSScreen * o_screen;    vout_thread_t * p_vout;    vlc_bool_t b_main_screen;        p_vout = (vout_thread_t *)[o_value pointerValue];    p_vout->p_sys->o_window = [VLCWindow alloc];    [p_vout->p_sys->o_window setVout: p_vout];    [p_vout->p_sys->o_window setReleasedWhenClosed: YES];    if( var_Get( p_vout, "video-device", &val ) < 0 )    {        o_screen = [NSScreen mainScreen];        b_main_screen = 1;    }    else    {        NSArray *o_screens = [NSScreen screens];        unsigned int i_index = val.i_int;                if( [o_screens count] < i_index )        {            o_screen = [NSScreen mainScreen];            b_main_screen = 1;        }        else        {            i_index--;            o_screen = [o_screens objectAtIndex: i_index];            config_PutInt( p_vout, "macosx-vdev", i_index );            b_main_screen = (i_index == 0);        }    }     if( p_vout->b_fullscreen && !p_vout->p_sys->i_opengl )    {        NSRect screen_rect = [o_screen frame];        screen_rect.origin.x = screen_rect.origin.y = 0;        if ( b_main_screen && p_vout->p_sys->p_fullscreen_state == NULL )            BeginFullScreen( &p_vout->p_sys->p_fullscreen_state, NULL, 0, 0,                             NULL, NULL, fullScreenAllowEvents );        [p_vout->p_sys->o_window             initWithContentRect: screen_rect            styleMask: NSBorderlessWindowMask            backing: NSBackingStoreBuffered            defer: NO screen: o_screen];        //[p_vout->p_sys->o_window setLevel: NSPopUpMenuWindowLevel - 1];        p_vout->p_sys->b_mouse_moved = YES;        p_vout->p_sys->i_time_mouse_last_moved = mdate();    }    else    {        unsigned int i_stylemask = NSTitledWindowMask |                                   NSMiniaturizableWindowMask |                                   NSClosableWindowMask |                                   NSResizableWindowMask;                if( !p_vout->p_sys->i_opengl )        {            if ( p_vout->p_sys->p_fullscreen_state != NULL )                EndFullScreen ( p_vout->p_sys->p_fullscreen_state, NULL );            p_vout->p_sys->p_fullscreen_state = NULL;        }        [p_vout->p_sys->o_window             initWithContentRect: p_vout->p_sys->s_rect            styleMask: i_stylemask            backing: NSBackingStoreBuffered            defer: NO screen: o_screen];        [p_vout->p_sys->o_window setAlphaValue: config_GetFloat( p_vout, "macosx-opaqueness" )];                if( config_GetInt( p_vout, "video-on-top" ) )        {            [p_vout->p_sys->o_window setLevel: NSStatusWindowLevel];        }                if( !p_vout->p_sys->b_pos_saved )           {            [p_vout->p_sys->o_window center];        }    }    if( !p_vout->p_sys->i_opengl )    {        o_view = [[VLCQTView alloc] init];        /* FIXME: [o_view setMenu:] */        [p_vout->p_sys->o_window setContentView: o_view];        [o_view autorelease];        [o_view lockFocus];        p_vout->p_sys->p_qdport = [o_view qdPort];        [o_view unlockFocus];    }    else    {#define o_glview p_vout->p_sys->o_glview        o_glview = [[VLCGLView alloc] initWithFrame: p_vout->p_sys->s_rect vout: p_vout];        [p_vout->p_sys->o_window setContentView: o_glview];        [o_glview autorelease];#undef o_glview    }        [p_vout->p_sys->o_window updateTitle];    [p_vout->p_sys->o_window makeKeyAndOrderFront: nil];}- (void)destroyWindow:(NSValue *)o_value{    vout_thread_t * p_vout;    p_vout = (vout_thread_t *)[o_value pointerValue];    if( !p_vout->b_fullscreen )    {        NSRect s_rect;        s_rect = [[p_vout->p_sys->o_window contentView] frame];        p_vout->p_sys->s_rect.size = s_rect.size;        s_rect = [p_vout->p_sys->o_window frame];        p_vout->p_sys->s_rect.origin = s_rect.origin;        p_vout->p_sys->b_pos_saved = YES;    }        p_vout->p_sys->p_qdport = nil;    [p_vout->p_sys->o_window close];    p_vout->p_sys->o_window = nil;}@end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?