VLCOpenGLVoutView.m
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * VLCOpenGLVoutView.m: MacOS X OpenGL provider
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2009 the VideoLAN team
  5.  * $Id: bb3b1c529f470ae6c7443aa8b04004cb6c7b215d $
  6.  *
  7.  * Authors: Colin Delacroix <colin@zoy.org>
  8.  *          Florian G. Pflug <fgp@phlo.org>
  9.  *          Jon Lech Johansen <jon-vl@nanocrew.net>
  10.  *          Derk-Jan Hartman <hartman at videolan dot org>
  11.  *          Eric Petit <titer@m0k.org>
  12.  *          Benjamin Pracht <bigben at videolan dot org>
  13.  *          Damien Fouilleul <damienf at videolan dot org>
  14.  *          Pierre d'Herbemont <pdherbemont at videolan dot org>
  15.  *
  16.  * This program is free software; you can redistribute it and/or modify
  17.  * it under the terms of the GNU General Public License as published by
  18.  * the Free Software Foundation; either version 2 of the License, or
  19.  * (at your option) any later version.
  20.  *
  21.  * This program is distributed in the hope that it will be useful,
  22.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  * GNU General Public License for more details.
  25.  *
  26.  * You should have received a copy of the GNU General Public License
  27.  * along with this program; if not, write to the Free Software
  28.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  29.  *****************************************************************************/
  30. /*****************************************************************************
  31.  * Preamble
  32.  *****************************************************************************/
  33. #include "intf.h"
  34. #include "voutgl.h"
  35. #include "VLCOpenGLVoutView.h"
  36. #include "VLCMinimalVoutWindow.h"
  37. #include <OpenGL/OpenGL.h>
  38. #include <OpenGL/gl.h>
  39. /*****************************************************************************
  40.  * cocoaglvoutviewInit
  41.  *****************************************************************************/
  42. int cocoaglvoutviewInit( vout_thread_t * p_vout )
  43. {
  44.     vlc_value_t value_drawable;
  45.     id <VLCOpenGLVoutEmbedding> o_cocoaglview_container;
  46.     msg_Dbg( p_vout, "Mac OS X Vout is opening" );
  47.     var_Create( p_vout, "drawable-nsobject", VLC_VAR_DOINHERIT );
  48.     var_Get( p_vout, "drawable-nsobject", &value_drawable );
  49.     p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
  50.     o_cocoaglview_container = (id) value_drawable.p_address;
  51.     if (!o_cocoaglview_container)
  52.     {
  53.         msg_Warn( p_vout, "No drawable!, spawing a window" );
  54.     }
  55.     p_vout->p_sys->b_embedded = false;
  56.     /* Create the GL view */
  57.     struct args { vout_thread_t * p_vout; id <VLCOpenGLVoutEmbedding> container; } args = { p_vout, o_cocoaglview_container };
  58.     [VLCOpenGLVoutView performSelectorOnMainThread:@selector(autoinitOpenGLVoutViewIntVoutWithContainer:)
  59.                         withObject:[NSData dataWithBytes: &args length: sizeof(struct args)] waitUntilDone:YES];
  60.     [[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
  61.     return VLC_SUCCESS;
  62. }
  63. /*****************************************************************************
  64.  * cocoaglvoutviewEnd
  65.  *****************************************************************************/
  66. void cocoaglvoutviewEnd( vout_thread_t * p_vout )
  67. {
  68.     id <VLCOpenGLVoutEmbedding> o_cocoaglview_container;
  69.     msg_Dbg( p_vout, "Mac OS X Vout is closing" );
  70.     var_Destroy( p_vout, "drawable-nsobject" );
  71.     o_cocoaglview_container = [p_vout->p_sys->o_glview container];
  72.     /* Make sure our view won't request the vout now */
  73.     [p_vout->p_sys->o_glview detachFromVout];
  74.     msg_Dbg( p_vout, "Mac OS X Vout is closing" );
  75.     /* Let the view go, _without_blocking_ */
  76.     [p_vout->p_sys->o_glview performSelectorOnMainThread:@selector(removeFromSuperview) withObject:NULL waitUntilDone:NO];
  77.     if( [(id)o_cocoaglview_container respondsToSelector:@selector(removeVoutSubview:)] )
  78.         [o_cocoaglview_container removeVoutSubview: p_vout->p_sys->o_glview];
  79.     [p_vout->p_sys->o_glview release];
  80.     [p_vout->p_sys->o_pool release];
  81.  
  82. }
  83. /*****************************************************************************
  84.  * cocoaglvoutviewManage
  85.  *****************************************************************************/
  86. int cocoaglvoutviewManage( vout_thread_t * p_vout )
  87. {
  88.     if( p_vout->i_changes & VOUT_ASPECT_CHANGE )
  89.     {
  90.         [p_vout->p_sys->o_glview reshape];
  91.         p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
  92.     }
  93.     if( p_vout->i_changes & VOUT_CROP_CHANGE )
  94.     {
  95.         [p_vout->p_sys->o_glview reshape];
  96.         p_vout->i_changes &= ~VOUT_CROP_CHANGE;
  97.     }
  98.     if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
  99.     {
  100.         NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
  101.         p_vout->b_fullscreen = !p_vout->b_fullscreen;
  102.         if( p_vout->b_fullscreen )
  103.             [[p_vout->p_sys->o_glview container] enterFullscreen];
  104.         else
  105.             [[p_vout->p_sys->o_glview container] leaveFullscreen];
  106.         [o_pool release];
  107.         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
  108.     }
  109.     //[[p_vout->p_sys->o_glview container] manage];
  110.     return VLC_SUCCESS;
  111. }
  112. /*****************************************************************************
  113.  * cocoaglvoutviewControl: control facility for the vout
  114.  *****************************************************************************/
  115. int cocoaglvoutviewControl( vout_thread_t *p_vout, int i_query, va_list args )
  116. {
  117.     bool b_arg;
  118.     switch( i_query )
  119.     {
  120.         case VOUT_SET_STAY_ON_TOP:
  121.             b_arg = (bool) va_arg( args, int );
  122.             [[p_vout->p_sys->o_glview container] setOnTop: b_arg];
  123.             return VLC_SUCCESS;
  124.         default:
  125.             return VLC_EGENERIC;
  126.     }
  127. }
  128. /*****************************************************************************
  129.  * cocoaglvoutviewSwap
  130.  *****************************************************************************/
  131. void cocoaglvoutviewSwap( vout_thread_t * p_vout )
  132. {
  133.     p_vout->p_sys->b_got_frame = true;
  134.     [[p_vout->p_sys->o_glview openGLContext] flushBuffer];
  135. }
  136. /*****************************************************************************
  137.  * cocoaglvoutviewLock
  138.  *****************************************************************************/
  139. int cocoaglvoutviewLock( vout_thread_t * p_vout )
  140. {
  141.     if( kCGLNoError == CGLLockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]) )
  142.     {
  143.         [[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
  144.         return 0;
  145.     }
  146.     return 1;
  147. }
  148. /*****************************************************************************
  149.  * cocoaglvoutviewUnlock
  150.  *****************************************************************************/
  151. void cocoaglvoutviewUnlock( vout_thread_t * p_vout )
  152. {
  153.     CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
  154. }
  155. /*****************************************************************************
  156.  * VLCOpenGLVoutView implementation
  157.  *****************************************************************************/
  158. @implementation VLCOpenGLVoutView
  159. /* Init a new gl view and register it to both the framework and the
  160.  * vout_thread_t. Must be called from main thread. */
  161. + (void) autoinitOpenGLVoutViewIntVoutWithContainer: (NSData *) argsAsData
  162. {
  163.     NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
  164.     struct args { vout_thread_t * p_vout; id <VLCOpenGLVoutEmbedding> container; } *
  165.         args = (struct args *)[argsAsData bytes];
  166.     VLCOpenGLVoutView * oglview;
  167.     if( !args->container )
  168.     {
  169.         args->container = [[VLCMinimalVoutWindow alloc] initWithContentRect: NSMakeRect( 0, 0, args->p_vout->i_window_width, args->p_vout->i_window_height )];
  170.         [(VLCMinimalVoutWindow *)args->container makeKeyAndOrderFront: nil];
  171.     }
  172.     oglview = [[VLCOpenGLVoutView alloc] initWithVout: args->p_vout container: args->container];
  173.     args->p_vout->p_sys->o_glview = oglview;
  174.     [args->container addVoutSubview: oglview];
  175.     [pool release];
  176. }
  177. - (void)dealloc
  178. {
  179.     [objectLock dealloc];
  180.     [super dealloc];
  181. }
  182. - (void)removeFromSuperview
  183. {
  184.     [super removeFromSuperview];
  185. }
  186. - (id) initWithVout: (vout_thread_t *) vout container: (id <VLCOpenGLVoutEmbedding>) aContainer
  187. {
  188.     NSOpenGLPixelFormatAttribute attribs[] =
  189.     {
  190.         NSOpenGLPFADoubleBuffer,
  191.         NSOpenGLPFAAccelerated,
  192.         NSOpenGLPFANoRecovery,
  193.         NSOpenGLPFAColorSize, 24,
  194.         NSOpenGLPFAAlphaSize, 8,
  195.         NSOpenGLPFADepthSize, 24,
  196.         NSOpenGLPFAWindow,
  197.         0
  198.     };
  199.     NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
  200.         initWithAttributes: attribs];
  201.     if( !fmt )
  202.     {
  203.         msg_Warn( p_vout, "could not create OpenGL video output" );
  204.         return nil;
  205.     }
  206.     if( self = [super initWithFrame: NSMakeRect(0,0,10,10) pixelFormat: fmt] )
  207.     {
  208.         p_vout = vout;
  209.         container = aContainer;
  210.         objectLock = [[NSLock alloc] init];
  211.         [fmt release];
  212.         [[self openGLContext] makeCurrentContext];
  213.         [[self openGLContext] update];
  214.         /* Swap buffers only during the vertical retrace of the monitor.
  215.         http://developer.apple.com/documentation/GraphicsImaging/
  216.         Conceptual/OpenGL/chap5/chapter_5_section_44.html */
  217.         GLint params[] = { 1 };
  218.         CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,
  219.                      params );
  220.     }
  221.     return self;
  222. }
  223. - (void) detachFromVout
  224. {
  225.     [objectLock lock];
  226.     p_vout = NULL;
  227.     [objectLock unlock];
  228. }
  229. - (id <VLCOpenGLVoutEmbedding>) container
  230. {
  231.     return container;
  232. }
  233. - (void) destroyVout
  234. {
  235.     [objectLock lock];
  236.     if( p_vout )
  237.     {
  238.         vlc_object_detach( p_vout );
  239.         vlc_object_release( p_vout );
  240.         vlc_object_release( p_vout );
  241.     }
  242.     [objectLock unlock];
  243. }
  244. - (void) reshape
  245. {
  246.     int x, y;
  247.     vlc_value_t val;
  248.     [objectLock lock];
  249.     if( !p_vout )
  250.     {
  251.         [objectLock unlock];
  252.         return;
  253.     }
  254.     cocoaglvoutviewLock( p_vout );
  255.     NSRect bounds = [self bounds];
  256.     if( [[self container] stretchesVideo] )
  257.     {
  258.         x = bounds.size.width;
  259.         y = bounds.size.height;
  260.     }
  261.     else if( bounds.size.height * p_vout->fmt_in.i_visible_width *
  262.              p_vout->fmt_in.i_sar_num <
  263.              bounds.size.width * p_vout->fmt_in.i_visible_height *
  264.              p_vout->fmt_in.i_sar_den )
  265.     {
  266.         x = ( bounds.size.height * p_vout->fmt_in.i_visible_width *
  267.               p_vout->fmt_in.i_sar_num ) /
  268.             ( p_vout->fmt_in.i_visible_height * p_vout->fmt_in.i_sar_den);
  269.         y = bounds.size.height;
  270.     }
  271.     else
  272.     {
  273.         x = bounds.size.width;
  274.         y = ( bounds.size.width * p_vout->fmt_in.i_visible_height *
  275.               p_vout->fmt_in.i_sar_den) /
  276.             ( p_vout->fmt_in.i_visible_width * p_vout->fmt_in.i_sar_num  );
  277.     }
  278.     glViewport( ( bounds.size.width - x ) / 2,
  279.                 ( bounds.size.height - y ) / 2, x, y );
  280.     if( p_vout->p_sys->b_got_frame )
  281.     {
  282.         /* Ask the opengl module to redraw */
  283.         vout_thread_t * p_parent;
  284.         p_parent = (vout_thread_t *) p_vout->p_parent;
  285.         cocoaglvoutviewUnlock( p_vout );
  286.         if( p_parent && p_parent->pf_display )
  287.         {
  288.             p_parent->pf_display( p_parent, NULL );
  289.         }
  290.     }
  291.     else
  292.     {
  293.         glClear( GL_COLOR_BUFFER_BIT );
  294.         cocoaglvoutviewUnlock( p_vout );
  295.     }
  296.     [objectLock unlock];
  297.     [super reshape];
  298. }
  299. - (void) update
  300. {
  301.     if( kCGLNoError != CGLLockContext([[self openGLContext] CGLContextObj]) )
  302.         return;
  303.     [super update];
  304.     CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
  305. }
  306. - (void) drawRect: (NSRect) rect
  307. {
  308.     if( kCGLNoError != CGLLockContext([[self openGLContext] CGLContextObj]) )
  309.         return;
  310.     [[self openGLContext] flushBuffer];
  311.     [super drawRect:rect];
  312.     CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
  313. }
  314. - (BOOL)mouseDownCanMoveWindow
  315. {
  316.     return YES;
  317. }
  318. @end