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 + -
显示快捷键?