📄 voutqt.m
字号:
while( I_OUTPUTPICTURES < QT_MAX_DIRECTBUFFERS ) { p_pic = NULL; /* Find an empty picture slot */ for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++ ) { if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) { p_pic = p_vout->p_picture + i_index; break; } } /* Allocate the picture */ if( p_pic == NULL || QTNewPicture( p_vout, p_pic ) ) { break; } p_pic->i_status = DESTROYED_PICTURE; p_pic->i_type = DIRECT_PICTURE; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; I_OUTPUTPICTURES++; } return 0;}/***************************************************************************** * EndVideo: terminate video thread output method *****************************************************************************/static void EndVideo( vout_thread_t *p_vout ){ int i_index; QTDestroySequence( p_vout ); if( !p_vout->b_fullscreen && p_vout->p_sys->b_embedded ) { var_DelCallback(p_vout->p_libvlc, "drawableredraw", DrawableRedraw, p_vout); DisposeRgn(p_vout->p_sys->clip_mask); } /* Free the direct buffers we allocated */ for( i_index = I_OUTPUTPICTURES; i_index; ) { i_index--; QTFreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] ); }}/***************************************************************************** * ManageVideo: handle events ***************************************************************************** * This function should be called regularly by video output thread. It manages * console events. It returns a non null value on error. *****************************************************************************/static int ManageVideo( vout_thread_t *p_vout ){ if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE ) { if( CoToggleFullscreen( p_vout ) ) { return( 1 ); } p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; } if( p_vout->i_changes & VOUT_SIZE_CHANGE ) { if( p_vout->b_fullscreen || !p_vout->p_sys->b_embedded ) { /* get the geometry from NSQuickDrawView */ Rect s_rect; GetPortBounds( p_vout->p_sys->p_qdport, &s_rect ); p_vout->p_sys->i_origx = s_rect.left; p_vout->p_sys->i_origy = s_rect.top; p_vout->p_sys->i_width = s_rect.right - s_rect.left; p_vout->p_sys->i_height = s_rect.bottom - s_rect.top; } else { /* As we're embedded, get the geometry from Mozilla/Safari NPWindow object */ UpdateEmbeddedGeometry( p_vout ); SetDSequenceMask(p_vout->p_sys->i_seq, p_vout->p_sys->clip_mask); } } if( p_vout->i_changes & VOUT_SIZE_CHANGE || p_vout->i_changes & VOUT_ASPECT_CHANGE ) { QTScaleMatrix( p_vout ); SetDSequenceMatrix( p_vout->p_sys->i_seq, p_vout->p_sys->p_matrix ); } if( p_vout->i_changes & VOUT_SIZE_CHANGE ) { p_vout->i_changes &= ~VOUT_SIZE_CHANGE; } if( p_vout->i_changes & VOUT_ASPECT_CHANGE ) { p_vout->i_changes &= ~VOUT_ASPECT_CHANGE; } // can be nil [p_vout->p_sys->o_vout_view manage]; return( 0 );}/***************************************************************************** * vout_Display: displays previously rendered output ***************************************************************************** * This function sends the currently rendered image to the display. *****************************************************************************/static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic ){ OSErr err; CodecFlags flags; if( (NULL == p_vout->p_sys->clip_mask) || !EmptyRgn(p_vout->p_sys->clip_mask) ) { //CGrafPtr oldPort; //Rect oldBounds; /* since there is not way to lock a QuickDraw port for exclusive use there is a potential problem that the frame will be displayed in the wrong place if other embedded plugins redraws as the port origin may be changed */ //GetPort(&oldPort); //GetPortBounds(p_vout->p_sys->p_qdport, &oldBounds); SetPort(p_vout->p_sys->p_qdport); SetOrigin(p_vout->p_sys->i_origx, p_vout->p_sys->i_origy); if( ( err = DecompressSequenceFrameWhen( p_vout->p_sys->i_seq, p_pic->p_sys->p_data, p_pic->p_sys->i_size, codecFlagUseImageBuffer, &flags, NULL, NULL ) == noErr ) ) { QDFlushPortBuffer( p_vout->p_sys->p_qdport, p_vout->p_sys->clip_mask ); //QDFlushPortBuffer( p_vout->p_sys->p_qdport, NULL ); } else { msg_Warn( p_vout, "QT failed to display the frame sequence: %d", err ); } //SetPortBounds(p_vout->p_sys->p_qdport, &oldBounds); //SetPort(oldPort); }}/***************************************************************************** * ControlVideo: control facility for the vout *****************************************************************************/static int ControlVideo( vout_thread_t *p_vout, int i_query, va_list args ){ bool b_arg; switch( i_query ) { case VOUT_SET_STAY_ON_TOP: b_arg = (bool) va_arg( args, int ); [p_vout->p_sys->o_vout_view setOnTop: b_arg]; return VLC_SUCCESS; case VOUT_CLOSE: case VOUT_REPARENT: default: return vout_vaControlDefault( p_vout, i_query, args ); }}/***************************************************************************** * CoToggleFullscreen: toggle fullscreen ***************************************************************************** * Returns 0 on success, 1 otherwise *****************************************************************************/static int CoToggleFullscreen( vout_thread_t *p_vout ){ NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; p_vout->b_fullscreen = !p_vout->b_fullscreen; if( p_vout->b_fullscreen ) [p_vout->p_sys->o_vout_view enterFullscreen]; else [p_vout->p_sys->o_vout_view leaveFullscreen]; [o_pool release]; return 0;}/* If we're embedded, the application is expected to indicate a * window change (move/resize/etc) via the "drawableredraw" value. * If that's the case, set the VOUT_SIZE_CHANGE flag so we do * actually handle the window change. */static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name, vlc_value_t oval, vlc_value_t nval, void *param){ /* ignore changes until we are ready for them */ if( (oval.i_int != nval.i_int) && (nval.i_int == 1) ) { vout_thread_t *p_vout = (vout_thread_t *)param; /* prevent QT from rendering any more video until we have updated the geometry */ SetEmptyRgn(p_vout->p_sys->clip_mask); SetDSequenceMask(p_vout->p_sys->i_seq, p_vout->p_sys->clip_mask); p_vout->i_changes |= VOUT_SIZE_CHANGE; } return VLC_SUCCESS;}/* Embedded video get their drawing region from the host application * by the drawable values here. Read those variables, and store them * in the p_vout->p_sys structure so that other functions (such as * DisplayVideo and ManageVideo) can use them later. */static void UpdateEmbeddedGeometry( vout_thread_t *p_vout ){ vlc_value_t val; vlc_value_t valt, vall, valb, valr, valx, valy, valw, valh, valportx, valporty; var_Get( p_vout->p_libvlc, "drawable", &val ); var_Get( p_vout->p_libvlc, "drawablet", &valt ); var_Get( p_vout->p_libvlc, "drawablel", &vall ); var_Get( p_vout->p_libvlc, "drawableb", &valb ); var_Get( p_vout->p_libvlc, "drawabler", &valr ); var_Get( p_vout->p_libvlc, "drawablex", &valx ); var_Get( p_vout->p_libvlc, "drawabley", &valy ); var_Get( p_vout->p_libvlc, "drawablew", &valw ); var_Get( p_vout->p_libvlc, "drawableh", &valh ); var_Get( p_vout->p_libvlc, "drawableportx", &valportx ); var_Get( p_vout->p_libvlc, "drawableporty", &valporty ); /* portx, porty contains values for SetOrigin() function which isn't used, instead use QT Translate matrix */ p_vout->p_sys->i_origx = valportx.i_int; p_vout->p_sys->i_origy = valporty.i_int; p_vout->p_sys->p_qdport = (CGrafPtr) val.i_int; p_vout->p_sys->i_width = valw.i_int; p_vout->p_sys->i_height = valh.i_int; /* update video clipping mask */ /*SetRectRgn( p_vout->p_sys->clip_mask , vall.i_int , valt.i_int, valr.i_int, valb.i_int );*/ SetRectRgn( p_vout->p_sys->clip_mask , vall.i_int + valportx.i_int , valt.i_int + valporty.i_int , valr.i_int + valportx.i_int , valb.i_int + valporty.i_int ); /* reset drawableredraw variable indicating we are ready to take changes in video geometry */ val.i_int=0; var_Set( p_vout->p_libvlc, "drawableredraw", val );}/***************************************************************************** * QTScaleMatrix: scale matrix *****************************************************************************/static void QTScaleMatrix( vout_thread_t *p_vout ){ vlc_value_t val; Fixed factor_x, factor_y; unsigned int i_offset_x = 0; unsigned int i_offset_y = 0; int i_width = p_vout->p_sys->i_width; int i_height = p_vout->p_sys->i_height; var_Get( p_vout, "macosx-stretch", &val ); if( val.b_bool ) { 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->fmt_in.i_visible_width * p_vout->fmt_in.i_sar_num < i_width * p_vout->fmt_in.i_visible_height * p_vout->fmt_in.i_sar_den ) { int i_adj_width = i_height * p_vout->fmt_in.i_visible_width * p_vout->fmt_in.i_sar_num / ( p_vout->fmt_in.i_sar_den * p_vout->fmt_in.i_visible_height ); factor_x = FixDiv( Long2Fix( i_adj_width ), Long2Fix( p_vout->fmt_in.i_visible_width ) ); factor_y = FixDiv( Long2Fix( i_height ), Long2Fix( p_vout->fmt_in.i_visible_height ) ); i_offset_x = (i_width - i_adj_width) / 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -