📄 voutqt.m
字号:
/***************************************************************************** * vout.m: MacOS X video output module ***************************************************************************** * Copyright (C) 2001-2007 the VideoLAN team * $Id$ * * Authors: Colin Delacroix <colin@zoy.org> * Florian G. Pflug <fgp@phlo.org> * Jon Lech Johansen <jon-vl@nanocrew.net> * Derk-Jan Hartman <hartman at videolan dot org> * Eric Petit <titer@m0k.org> * Benjamin Pracht <bigben AT videolan DOT org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h> /* free() */#include <string.h>#include <assert.h>#include <QuickTime/QuickTime.h>#include <vlc_keys.h>#include "intf.h"#include "vout.h"#define QT_MAX_DIRECTBUFFERS 10#define VL_MAX_DISPLAYS 16/***************************************************************************** * VLCView interface *****************************************************************************/@interface VLCQTView : NSQuickDrawView <VLCVoutViewResetting>{ vout_thread_t * p_vout;}+ (void)resetVout: (vout_thread_t *)p_vout;- (id) initWithVout:(vout_thread_t *)p_vout;@endstruct vout_sys_t{ NSAutoreleasePool *o_pool; VLCQTView * o_qtview; VLCVoutView * o_vout_view; bool b_saved_frame; bool b_cpu_has_simd; /* does CPU supports Altivec, MMX, etc... */ NSRect s_frame; CodecType i_codec; CGrafPtr p_qdport; ImageSequence i_seq; MatrixRecordPtr p_matrix; DecompressorComponent img_dc; ImageDescriptionHandle h_img_descr; /* video geometry in port */ int i_origx, i_origy; int i_width, i_height; /* Mozilla plugin-related variables */ bool b_embedded; RgnHandle clip_mask;};struct picture_sys_t{ void *p_data; unsigned int i_size; /* When using I420 output */ PlanarPixmapInfoYUV420 pixmap_i420;};/***************************************************************************** * Local prototypes *****************************************************************************/static int InitVideo ( vout_thread_t * );static void EndVideo ( vout_thread_t * );static int ManageVideo ( vout_thread_t * );static void DisplayVideo ( vout_thread_t *, picture_t * );static int ControlVideo ( vout_thread_t *, int, va_list );static int CoToggleFullscreen( vout_thread_t *p_vout );static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name, vlc_value_t oval, vlc_value_t nval, void *param);static void UpdateEmbeddedGeometry( vout_thread_t *p_vout );static void QTScaleMatrix ( vout_thread_t * );static int QTCreateSequence ( vout_thread_t * );static void QTDestroySequence ( vout_thread_t * );static int QTNewPicture ( vout_thread_t *, picture_t * );static void QTFreePicture ( vout_thread_t *, picture_t * );/***************************************************************************** * OpenVideo: allocates MacOS X video thread output method ***************************************************************************** * This function allocates and initializes a MacOS X vout method. *****************************************************************************/int OpenVideoQT ( vlc_object_t *p_this ){ vout_thread_t * p_vout = (vout_thread_t *)p_this; OSErr err; vlc_value_t value_drawable; p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) { msg_Err( p_vout, "out of memory" ); return( 1 ); } memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) ); p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init]; p_vout->pf_init = InitVideo; p_vout->pf_end = EndVideo; p_vout->pf_manage = ManageVideo; p_vout->pf_render = NULL; p_vout->pf_display = DisplayVideo; p_vout->pf_control = ControlVideo; /* Are we embedded? If so, the drawable value will be a pointer to a * CGrafPtr that we're expected to use */ var_Get( p_vout->p_libvlc, "drawable", &value_drawable ); if( value_drawable.i_int != 0 ) p_vout->p_sys->b_embedded = true; else p_vout->p_sys->b_embedded = false; p_vout->p_sys->b_cpu_has_simd = vlc_CPU() & (CPU_CAPABILITY_ALTIVEC|CPU_CAPABILITY_MMXEXT); msg_Dbg( p_vout, "we do%s have SIMD enabled CPU", p_vout->p_sys->b_cpu_has_simd ? "" : "n't" ); /* Initialize QuickTime */ p_vout->p_sys->h_img_descr = (ImageDescriptionHandle)NewHandleClear( sizeof(ImageDescription) ); p_vout->p_sys->p_matrix = (MatrixRecordPtr)malloc( sizeof(MatrixRecord) ); if( ( err = EnterMovies() ) != noErr ) { msg_Err( p_vout, "QT initialization failed: EnterMovies failed: %d", err ); free( p_vout->p_sys->p_matrix ); DisposeHandle( (Handle)p_vout->p_sys->h_img_descr ); free( p_vout->p_sys ); return VLC_EGENERIC; } /* Damn QT isn't thread safe, so keep a process-wide lock */ vlc_mutex_t *p_qtlock = var_AcquireMutex( "quicktime_mutex" ); /* Can we find the right chroma ? */ if( p_vout->p_sys->b_cpu_has_simd ) { err = FindCodec( kYUVSPixelFormat, bestSpeedCodec, nil, &p_vout->p_sys->img_dc ); } else { err = FindCodec( kYUV420CodecType, bestSpeedCodec, nil, &p_vout->p_sys->img_dc ); } vlc_mutex_unlock( p_qtlock ); if( err == noErr && p_vout->p_sys->img_dc != 0 ) { if( p_vout->p_sys->b_cpu_has_simd ) { p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2'); p_vout->p_sys->i_codec = kYUVSPixelFormat; } else { p_vout->output.i_chroma = VLC_FOURCC('I','4','2','0'); p_vout->p_sys->i_codec = kYUV420CodecType; } } else { msg_Err( p_vout, "QT doesn't support any appropriate chroma" ); } if( p_vout->p_sys->img_dc == 0 ) { free( p_vout->p_sys->p_matrix ); DisposeHandle( (Handle)p_vout->p_sys->h_img_descr ); free( p_vout->p_sys ); return VLC_EGENERIC; } if( p_vout->b_fullscreen || !p_vout->p_sys->b_embedded ) { /* Spawn window */#define o_qtview p_vout->p_sys->o_qtview o_qtview = [[VLCQTView alloc] initWithVout: p_vout]; [o_qtview autorelease]; p_vout->p_sys->o_vout_view = [VLCVoutView getVoutView: p_vout subView: o_qtview frame: nil]; if( !p_vout->p_sys->o_vout_view ) { return VLC_EGENERIC; } [o_qtview lockFocus]; p_vout->p_sys->p_qdport = [o_qtview qdPort]; [o_qtview unlockFocus]; }#undef o_qtview return VLC_SUCCESS;}/***************************************************************************** * CloseVideo: destroy video thread output method *****************************************************************************/void CloseVideoQT ( vlc_object_t *p_this ){ NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; vout_thread_t * p_vout = (vout_thread_t *)p_this; if( p_vout->b_fullscreen || !p_vout->p_sys->b_embedded ) [p_vout->p_sys->o_vout_view closeVout]; /* Clean Up Quicktime environment */ ExitMovies(); free( p_vout->p_sys->p_matrix ); DisposeHandle( (Handle)p_vout->p_sys->h_img_descr ); [o_pool release]; free( p_vout->p_sys );}/***************************************************************************** * InitVideo: initialize video thread output method *****************************************************************************/static int InitVideo ( vout_thread_t *p_vout ){ picture_t *p_pic; int i_index; I_OUTPUTPICTURES = 0; /* Initialize the output structure; we already found a codec, * and the corresponding chroma we will be using. Since we can * arbitrary scale, stick to the coordinates and aspect. */ p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_aspect = p_vout->render.i_aspect; if( p_vout->b_fullscreen || !p_vout->p_sys->b_embedded ) { Rect s_rect; p_vout->p_sys->clip_mask = NULL; 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 are embedded (e.g. running as a Mozilla plugin), use the pointer * stored in the "drawable" value as the CGrafPtr for the QuickDraw * graphics port */ /* Create the clipping mask */ p_vout->p_sys->clip_mask = NewRgn(); UpdateEmbeddedGeometry(p_vout); var_AddCallback(p_vout->p_libvlc, "drawableredraw", DrawableRedraw, p_vout); } QTScaleMatrix( p_vout ); if( QTCreateSequence( p_vout ) ) { msg_Err( p_vout, "unable to initialize QT: QTCreateSequence failed" ); return( 1 ); } /* Try to initialize up to QT_MAX_DIRECTBUFFERS direct buffers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -