vout.m
来自「VLC媒体播放程序」· M 代码 · 共 1,859 行 · 第 1/4 页
M
1,859 行
* This function sends the currently rendered image to the display. *****************************************************************************/static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic ){ if( !p_vout->p_sys->i_opengl ) { OSErr err; CodecFlags flags; if( ( err = DecompressSequenceFrameS( p_vout->p_sys->i_seq, p_pic->p_sys->p_info, p_pic->p_sys->i_size, codecFlagUseImageBuffer, &flags, nil ) != noErr ) ) { msg_Warn( p_vout, "DecompressSequenceFrameS failed: %d", err ); } else { QDFlushPortBuffer( p_vout->p_sys->p_qdport, nil ); } } else { if( [p_vout->p_sys->o_glview lockFocusIfCanDraw] ) { /* Texture gotta be reload before the buffer is filled (thanks to gcc from arstechnica forums) */ [p_vout->p_sys->o_glview drawRect: [p_vout->p_sys->o_glview bounds]]; [p_vout->p_sys->o_glview reloadTexture]; [p_vout->p_sys->o_glview unlockFocus]; } }}/***************************************************************************** * CoSendRequest: send request to interface thread ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int CoSendRequest( vout_thread_t *p_vout, SEL sel ){ int i_ret = 0; vlc_value_t val; intf_thread_t * p_intf; VLCVout * o_vlv = [[VLCVout alloc] init]; if( ( i_ret = ExecuteOnMainThread( o_vlv, sel, (void *)p_vout ) ) ) { msg_Err( p_vout, "SendRequest: no way to communicate with mt" ); } [o_vlv release]; /*This makes this function dependant of the presence of a macosx interface. We do not check if this interface exists, since it has already been done before.*/ p_intf = [NSApp getIntf]; val.b_bool = VLC_TRUE; var_Create(p_intf,"intf-change",VLC_VAR_BOOL); var_Set(p_intf, "intf-change",val); return( i_ret );}/***************************************************************************** * CoCreateWindow: create new window ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int CoCreateWindow( vout_thread_t *p_vout ){ if( CoSendRequest( p_vout, @selector(createWindow:) ) ) { msg_Err( p_vout, "CoSendRequest (createWindow) failed" ); return( 1 ); } return( 0 );}/***************************************************************************** * CoDestroyWindow: destroy window ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int CoDestroyWindow( vout_thread_t *p_vout ){ VLCHideMouse( p_vout, NO ); if( CoSendRequest( p_vout, @selector(destroyWindow:) ) ) { msg_Err( p_vout, "CoSendRequest (destroyWindow) failed" ); return( 1 ); } return( 0 );}/***************************************************************************** * CoToggleFullscreen: toggle fullscreen ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int CoToggleFullscreen( vout_thread_t *p_vout ){ if( p_vout->p_sys->i_opengl ) { p_vout->b_fullscreen = !p_vout->b_fullscreen; if( p_vout->b_fullscreen ) { [p_vout->p_sys->o_glview goFullScreen]; } else { [p_vout->p_sys->o_glview exitFullScreen]; } return 0; } QTDestroySequence( p_vout ); if( CoDestroyWindow( p_vout ) ) { msg_Err( p_vout, "unable to destroy window" ); return( 1 ); } p_vout->b_fullscreen = !p_vout->b_fullscreen; if( CoCreateWindow( p_vout ) ) { msg_Err( p_vout, "unable to create window" ); return( 1 ); } SetPort( p_vout->p_sys->p_qdport ); QTScaleMatrix( p_vout ); if( QTCreateSequence( p_vout ) ) { msg_Err( p_vout, "unable to create sequence" ); return( 1 ); } return( 0 );}/***************************************************************************** * VLCHideMouse: if b_hide then hide the cursor *****************************************************************************/static void VLCHideMouse ( vout_thread_t *p_vout, BOOL b_hide ){ BOOL b_inside; NSRect s_rect; NSPoint ml; NSWindow *o_window = p_vout->p_sys->o_window; NSView *o_contents = [o_window contentView]; s_rect = [o_contents bounds]; ml = [o_window convertScreenToBase:[NSEvent mouseLocation]]; ml = [o_contents convertPoint:ml fromView:nil]; b_inside = [o_contents mouse: ml inRect: s_rect]; if ( b_hide && b_inside ) { /* only hide if mouse over VLCQTView */ [NSCursor setHiddenUntilMouseMoves: YES]; } else if ( !b_hide ) { [NSCursor setHiddenUntilMouseMoves: NO]; } p_vout->p_sys->b_mouse_moved = NO; p_vout->p_sys->i_time_mouse_last_moved = mdate(); return;}/***************************************************************************** * QTScaleMatrix: scale matrix *****************************************************************************/static void QTScaleMatrix( vout_thread_t *p_vout ){ Rect s_rect; unsigned int i_width, i_height; Fixed factor_x, factor_y; unsigned int i_offset_x = 0; unsigned int i_offset_y = 0; GetPortBounds( p_vout->p_sys->p_qdport, &s_rect ); i_width = s_rect.right - s_rect.left; i_height = s_rect.bottom - s_rect.top; if( config_GetInt( p_vout, "macosx-stretch" ) ) { factor_x = FixDiv( Long2Fix( i_width ), Long2Fix( p_vout->output.i_width ) ); factor_y = FixDiv( Long2Fix( i_height ), Long2Fix( p_vout->output.i_height ) ); } else if( i_height * p_vout->output.i_aspect < i_width * VOUT_ASPECT_FACTOR ) { int i_adj_width = i_height * p_vout->output.i_aspect / VOUT_ASPECT_FACTOR; factor_x = FixDiv( Long2Fix( i_adj_width ), Long2Fix( p_vout->output.i_width ) ); factor_y = FixDiv( Long2Fix( i_height ), Long2Fix( p_vout->output.i_height ) ); i_offset_x = (i_width - i_adj_width) / 2; } else { int i_adj_height = i_width * VOUT_ASPECT_FACTOR / p_vout->output.i_aspect; factor_x = FixDiv( Long2Fix( i_width ), Long2Fix( p_vout->output.i_width ) ); factor_y = FixDiv( Long2Fix( i_adj_height ), Long2Fix( p_vout->output.i_height ) ); i_offset_y = (i_height - i_adj_height) / 2; } SetIdentityMatrix( p_vout->p_sys->p_matrix ); ScaleMatrix( p_vout->p_sys->p_matrix, factor_x, factor_y, Long2Fix(0), Long2Fix(0) ); TranslateMatrix( p_vout->p_sys->p_matrix, Long2Fix(i_offset_x), Long2Fix(i_offset_y) );}/***************************************************************************** * QTCreateSequence: create a new sequence ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int QTCreateSequence( vout_thread_t *p_vout ){ OSErr err; ImageDescriptionPtr p_descr; HLock( (Handle)p_vout->p_sys->h_img_descr ); p_descr = *p_vout->p_sys->h_img_descr; p_descr->idSize = sizeof(ImageDescription); p_descr->cType = p_vout->p_sys->i_codec; p_descr->version = 1; p_descr->revisionLevel = 0; p_descr->vendor = 'appl'; p_descr->width = p_vout->output.i_width; p_descr->height = p_vout->output.i_height; p_descr->hRes = Long2Fix(72); p_descr->vRes = Long2Fix(72); p_descr->spatialQuality = codecLosslessQuality; p_descr->frameCount = 1; p_descr->clutID = -1; p_descr->dataSize = 0; p_descr->depth = 24; HUnlock( (Handle)p_vout->p_sys->h_img_descr ); if( ( err = DecompressSequenceBeginS( &p_vout->p_sys->i_seq, p_vout->p_sys->h_img_descr, NULL, 0, p_vout->p_sys->p_qdport, NULL, NULL, p_vout->p_sys->p_matrix, 0, NULL, codecFlagUseImageBuffer, codecLosslessQuality, p_vout->p_sys->img_dc ) ) ) { msg_Err( p_vout, "DecompressSequenceBeginS failed: %d", err ); return( 1 ); } return( 0 );}/***************************************************************************** * QTDestroySequence: destroy sequence *****************************************************************************/static void QTDestroySequence( vout_thread_t *p_vout ){ CDSequenceEnd( p_vout->p_sys->i_seq );}/***************************************************************************** * QTNewPicture: allocate a picture ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int QTNewPicture( vout_thread_t *p_vout, picture_t *p_pic ){ int i_width = p_vout->output.i_width; int i_height = p_vout->output.i_height; /* We know the chroma, allocate a buffer which will be used * directly by the decoder */ p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); if( p_pic->p_sys == NULL ) { return( -1 ); } switch( p_vout->output.i_chroma ) { case VLC_FOURCC('I','4','2','0'): p_pic->p_sys->p_info = (void *)&p_pic->p_sys->pixmap_i420; p_pic->p_sys->i_size = sizeof(PlanarPixmapInfoYUV420); /* Allocate the memory buffer */ p_pic->p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_width * i_height * 3 / 2 ); /* Y buffer */ p_pic->Y_PIXELS = p_pic->p_data; p_pic->p[Y_PLANE].i_lines = i_height; p_pic->p[Y_PLANE].i_pitch = i_width; p_pic->p[Y_PLANE].i_pixel_pitch = 1; p_pic->p[Y_PLANE].i_visible_pitch = i_width; /* U buffer */ p_pic->U_PIXELS = p_pic->Y_PIXELS + i_height * i_width; p_pic->p[U_PLANE].i_lines = i_height / 2; p_pic->p[U_PLANE].i_pitch = i_width / 2; p_pic->p[U_PLANE].i_pixel_pitch = 1; p_pic->p[U_PLANE].i_visible_pitch = i_width / 2; /* V buffer */ p_pic->V_PIXELS = p_pic->U_PIXELS + i_height * i_width / 4; p_pic->p[V_PLANE].i_lines = i_height / 2; p_pic->p[V_PLANE].i_pitch = i_width / 2; p_pic->p[V_PLANE].i_pixel_pitch = 1; p_pic->p[V_PLANE].i_visible_pitch = i_width / 2; /* We allocated 3 planes */ p_pic->i_planes = 3;#define P p_pic->p_sys->pixmap_i420 P.componentInfoY.offset = (void *)p_pic->Y_PIXELS - p_pic->p_sys->p_info; P.componentInfoCb.offset = (void *)p_pic->U_PIXELS - p_pic->p_sys->p_info; P.componentInfoCr.offset = (void *)p_pic->V_PIXELS - p_pic->p_sys->p_info; P.componentInfoY.rowBytes = i_width; P.componentInfoCb.rowBytes = i_width / 2; P.componentInfoCr.rowBytes = i_width / 2;#undef P break; default: /* Unknown chroma, tell the guy to get lost */ free( p_pic->p_sys ); msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)", p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma ); p_pic->i_planes = 0; return( -1 ); } return( 0 );}/***************************************************************************** * QTFreePicture: destroy a picture allocated with QTNewPicture *****************************************************************************/static void QTFreePicture( vout_thread_t *p_vout, picture_t *p_pic ){ switch( p_vout->output.i_chroma ) { case VLC_FOURCC('I','4','2','0'): free( p_pic->p_data_orig ); break; } free( p_pic->p_sys );}/***************************************************************************** * VLCWindow implementation *****************************************************************************/@implementation VLCWindow- (void)setVout:(vout_thread_t *)_p_vout{ p_vout = _p_vout;}- (vout_thread_t *)getVout{ return( p_vout );}- (void)scaleWindowWithFactor: (float)factor{ NSSize newsize; int i_corrected_height, i_corrected_width; NSPoint topleftbase; NSPoint topleftscreen; if ( !p_vout->b_fullscreen ) { topleftbase.x = 0; topleftbase.y = [self frame].size.height; topleftscreen = [self convertBaseToScreen: topleftbase]; if( p_vout->output.i_height * p_vout->output.i_aspect > p_vout->output.i_width * VOUT_ASPECT_FACTOR ) { i_corrected_width = p_vout->output.i_height * p_vout->output.i_aspect / VOUT_ASPECT_FACTOR; newsize.width = (int) ( i_corrected_width * factor ); newsize.height = (int) ( p_vout->render.i_height * factor ); } else { i_corrected_height = p_vout->output.i_width * VOUT_ASPECT_FACTOR / p_vout->output.i_aspect; newsize.width = (int) ( p_vout->render.i_width * factor ); newsize.height = (int) ( i_corrected_height * factor ); } [self setContentSize: newsize]; [self setFrameTopLeftPoint: topleftscreen]; p_vout->i_changes |= VOUT_SIZE_CHANGE; }}- (void)toggleFloatOnTop{ if( config_GetInt( p_vout, "video-on-top" ) ) { config_PutInt( p_vout, "video-on-top", 0 ); [p_vout->p_sys->o_window setLevel: NSNormalWindowLevel]; } else { config_PutInt( p_vout, "video-on-top", 1 ); [p_vout->p_sys->o_window setLevel: NSStatusWindowLevel]; }}- (void)toggleFullscreen{ config_PutInt(p_vout, "fullscreen", !p_vout->b_fullscreen); p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?