video_output/opengllayer.m:
authorPierre d'Herbemont <pdherbemont@videolan.org>
Sun, 6 Jan 2008 17:58:17 +0000 (17:58 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Sun, 6 Jan 2008 17:58:17 +0000 (17:58 +0000)
* Code simplification. Green flashes removal. Call display instead of setNeedsDisplay: to make sure we have a frame per fram
e accuracy. Use removeVoutLayer: to detach the drawer from its drawable.
MacOSX/Framework:
* Code factorization from VLCVideoView, VLCVideoLayer in VLCVideoCommon
* Implement removeVoutLayer: as needed by the opengllayer.

extras/MacOSX/Framework/Headers/Internal/VLCVideoCommon.h [new file with mode: 0644]
extras/MacOSX/Framework/Headers/Public/VLCVideoView.h
extras/MacOSX/Framework/Sources/VLCVideoCommon.m [new file with mode: 0644]
extras/MacOSX/Framework/Sources/VLCVideoLayer.m
extras/MacOSX/Framework/Sources/VLCVideoView.m
extras/MacOSX/Framework/VLC.xcodeproj/project.pbxproj
modules/video_output/opengllayer.m

diff --git a/extras/MacOSX/Framework/Headers/Internal/VLCVideoCommon.h b/extras/MacOSX/Framework/Headers/Internal/VLCVideoCommon.h
new file mode 100644 (file)
index 0000000..b1b06aa
--- /dev/null
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * VLCVideoCommon.h: VLC.framework VLCVideoCommon header
+ *****************************************************************************
+ * Copyright (C) 2007 Pierre d'Herbemont
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id: VLCVideoCommon.h 23915 2007-12-28 22:20:19Z pdherbemont $
+ *
+ * Authors: Pierre d'Herbemont <pdherbemont # videolan.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.
+ *****************************************************************************/
+
+#import <QuartzCore/QuartzCore.h>
+
+@interface VLCVideoLayoutManager : NSObject
+{
+    CGSize originalVideoSize;
+    BOOL  fillScreenEntirely;
+}
+@property BOOL  fillScreenEntirely;
+@property CGSize originalVideoSize;
+
++ (id)layoutManager;
+
+@end
+/*****************************************************************************
+ * VLCVideoCommon.h: VLC.framework VLCVideoCommon header
+ *****************************************************************************
+ * Copyright (C) 2007 Pierre d'Herbemont
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id: VLCVideoCommon.h 23915 2007-12-28 22:20:19Z pdherbemont $
+ *
+ * Authors: Pierre d'Herbemont <pdherbemont # videolan.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.
+ *****************************************************************************/
+
+#import <QuartzCore/QuartzCore.h>
+
+@interface VLCVideoLayoutManager : NSObject
+{
+    CGSize originalVideoSize;
+    BOOL  fillScreenEntirely;
+}
+@property BOOL  fillScreenEntirely;
+@property CGSize originalVideoSize;
+
++ (id)layoutManager;
+
+@end
index 9ba42b3..8006ea2 100644 (file)
@@ -25,8 +25,6 @@
 #import <Cocoa/Cocoa.h>
 #import <QuartzCore/QuartzCore.h>
 
-@class CALayer;
-
 @interface VLCVideoView : NSView
 {
     id delegate;
diff --git a/extras/MacOSX/Framework/Sources/VLCVideoCommon.m b/extras/MacOSX/Framework/Sources/VLCVideoCommon.m
new file mode 100644 (file)
index 0000000..a69299c
--- /dev/null
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * VLCVideoCommon.m: VLC.framework VLCVideoCommon implementation
+ *****************************************************************************
+ * Copyright (C) 2007 Pierre d'Herbemont
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id: VLCVideoCommon.m 23915 2007-12-28 22:20:19Z pdherbemont $
+ *
+ * Authors: Pierre d'Herbemont <pdherbemont # videolan.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.
+ *****************************************************************************/
+
+#import "VLCVideoCommon.h"
+
+/******************************************************************************
+ * Implementation VLCVideoLayoutManager
+ *
+ * Manage the size of the video layer 
+ */
+
+@implementation VLCVideoLayoutManager 
+@synthesize  fillScreenEntirely;
+@synthesize  originalVideoSize;
+
++ (id)layoutManager
+{
+    return [[[self alloc] init] autorelease];
+}
+
+- (void)layoutSublayersOfLayer:(CALayer *)layer
+{
+    /* After having done everything normally resize the vlcopengllayer */
+    if( [[layer sublayers] count] > 0 && [[[[layer sublayers] objectAtIndex:0] name] isEqualToString:@"vlcopengllayer"])
+    {
+        CALayer * videolayer = [[layer sublayers] objectAtIndex:0];
+        CGRect bounds = layer.bounds;
+        CGRect videoRect = bounds;
+        
+        CGFloat xRatio = CGRectGetWidth(bounds)/originalVideoSize.width;
+        CGFloat yRatio = CGRectGetHeight(bounds)/originalVideoSize.height;
+        CGFloat ratio = fillScreenEntirely ? MAX(xRatio, yRatio) : MIN(xRatio, yRatio);
+        
+        videoRect.size.width = ratio*originalVideoSize.width;
+        videoRect.size.height = ratio*originalVideoSize.height;
+        videoRect.origin.x += (CGRectGetWidth(bounds) - CGRectGetWidth(videoRect))/2.0;
+        videoRect.origin.y += (CGRectGetHeight(bounds) - CGRectGetHeight(videoRect))/2.0;
+        
+        videolayer.frame = videoRect;
+    }
+}
+@end
+/*****************************************************************************
+ * VLCVideoCommon.m: VLC.framework VLCVideoCommon implementation
+ *****************************************************************************
+ * Copyright (C) 2007 Pierre d'Herbemont
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id: VLCVideoCommon.m 23915 2007-12-28 22:20:19Z pdherbemont $
+ *
+ * Authors: Pierre d'Herbemont <pdherbemont # videolan.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.
+ *****************************************************************************/
+
+#import "VLCVideoCommon.h"
+
+/******************************************************************************
+ * Implementation VLCVideoLayoutManager
+ *
+ * Manage the size of the video layer 
+ */
+
+@implementation VLCVideoLayoutManager 
+@synthesize  fillScreenEntirely;
+@synthesize  originalVideoSize;
+
++ (id)layoutManager
+{
+    return [[[self alloc] init] autorelease];
+}
+
+- (void)layoutSublayersOfLayer:(CALayer *)layer
+{
+    /* After having done everything normally resize the vlcopengllayer */
+    if( [[layer sublayers] count] > 0 && [[[[layer sublayers] objectAtIndex:0] name] isEqualToString:@"vlcopengllayer"])
+    {
+        CALayer * videolayer = [[layer sublayers] objectAtIndex:0];
+        CGRect bounds = layer.bounds;
+        CGRect videoRect = bounds;
+        
+        CGFloat xRatio = CGRectGetWidth(bounds)/originalVideoSize.width;
+        CGFloat yRatio = CGRectGetHeight(bounds)/originalVideoSize.height;
+        CGFloat ratio = fillScreenEntirely ? MAX(xRatio, yRatio) : MIN(xRatio, yRatio);
+        
+        videoRect.size.width = ratio*originalVideoSize.width;
+        videoRect.size.height = ratio*originalVideoSize.height;
+        videoRect.origin.x += (CGRectGetWidth(bounds) - CGRectGetWidth(videoRect))/2.0;
+        videoRect.origin.y += (CGRectGetHeight(bounds) - CGRectGetHeight(videoRect))/2.0;
+        
+        videolayer.frame = videoRect;
+    }
+}
+@end
index 3e17a33..bebca9b 100644 (file)
@@ -25,6 +25,7 @@
 #import "VLCVideoLayer.h"
 #import "VLCLibrary.h"
 #import "VLCEventManager.h"
+#import "VLCVideoCommon.h"
 
 /* Libvlc */
 #include <vlc/vlc.h>
@@ -47,8 +48,6 @@
 
 @implementation VLCVideoLayer
 
-/* Nothing */
-
 @end
 
 /******************************************************************************
 /* This is called by the libvlc module 'opengllayer' as soon as there is one 
  * vout available
  */
-- (void)addVoutLayer:(CALayer *)aLayer
+- (void)addVoutLayer:(CALayer *)voutLayer
 {
     [CATransaction begin];
+    voutLayer.name = @"vlcopengllayer";
+    
+    VLCVideoLayoutManager * layoutManager = [VLCVideoLayoutManager layoutManager];
+    layoutManager.originalVideoSize = voutLayer.bounds.size;
+    self.layoutManager = layoutManager;
+    
+    [self insertSublayer:voutLayer atIndex:0];
 
-    aLayer.name = @"vlcopengllayer";
-
-    [aLayer setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
-
-    [self insertSublayer:aLayer atIndex:0];
-
-    [aLayer setNeedsLayout];
-    [aLayer setNeedsDisplay];
-    [self setNeedsDisplay];
-    [self layoutIfNeeded];
+    [CATransaction commit];
+}
 
+- (void)removeVoutLayer:(CALayer*)voutLayer
+{
+    [CATransaction begin];
+    [voutLayer removeFromSuperlayer];
     [CATransaction commit];
 }
 
index 3326f11..40c6093 100644 (file)
@@ -25,6 +25,7 @@
 #import "VLCVideoView.h"
 #import "VLCLibrary.h"
 #import "VLCEventManager.h"
+#import "VLCVideoCommon.h"
 
 /* Libvlc */
 #include <vlc/vlc.h>
 - (void)addVoutLayer:(CALayer *)aLayer;
 @end
 
-/******************************************************************************
- * Interface & Implementation VLCConstraintLayoutManager
- *
- * Manage the size of the video layer 
- */
-@interface VLCConstraintLayoutManager : CAConstraintLayoutManager
-{
-    CGSize originalVideoSize;
-    BOOL  fillScreenEntirely;
-}
-@property BOOL  fillScreenEntirely;
-@property CGSize originalVideoSize;
-@end
-
-@implementation VLCConstraintLayoutManager 
-@synthesize  fillScreenEntirely;
-@synthesize  originalVideoSize;
-- (id)init
-{
-    if( self = [super init] )
-    {
-        self.originalVideoSize = CGSizeMake(0., 0.);
-        self.fillScreenEntirely = NO;
-    }
-    return self;
-
-}
-+ (id)layoutManager
-{
-    return [[[VLCConstraintLayoutManager alloc] init] autorelease];
-}
-- (void)layoutSublayersOfLayer:(CALayer *)layer
-{
-    /* Called by CA, when our rootLayer needs layout */
-    [super layoutSublayersOfLayer:layer];
-
-    /* After having done everything normally resize the vlcopengllayer */
-    if( [[layer sublayers] count] > 0 && [[[[layer sublayers] objectAtIndex:0] name] isEqualToString:@"vlcopengllayer"])
-    {
-        CALayer * videolayer = [[layer sublayers] objectAtIndex:0];
-        CGRect bounds = layer.bounds;
-        float new_height = (bounds.size.width * originalVideoSize.height) / originalVideoSize.width;
-
-        if( fillScreenEntirely )
-        {
-            if( bounds.size.height > new_height )
-                bounds.size.height = new_height;
-            else
-                bounds.size.width = (bounds.size.height * originalVideoSize.width) / originalVideoSize.height;
-        }
-        else
-        {
-            if( bounds.size.height > new_height )
-                bounds.size.width = (bounds.size.height * originalVideoSize.width) / originalVideoSize.height;
-            else
-                bounds.size.height = new_height;
-        }
-
-        bounds.origin = CGPointMake( 0.0, 0.0 );
-        videolayer.bounds = bounds;
-        videolayer.position = CGPointMake((layer.bounds.size.width - layer.bounds.origin.x)/2, (layer.bounds.size.height - layer.bounds.origin.y)/2);
-    }
-}
-@end
-
 /******************************************************************************
  * Implementation VLCVideoView 
  */
         [self setStretchesVideo:NO];
         [self setAutoresizesSubviews:YES];
         [self setFillScreen: NO];
-        layoutManager = [[VLCConstraintLayoutManager layoutManager] retain];
+        layoutManager = [[VLCVideoLayoutManager layoutManager] retain];
     }
     return self;
 }
     [CATransaction commit];
 }
 
+- (void)removeVoutLayer:(CALayer*)voutLayer
+{
+    [CATransaction begin];
+    [voutLayer removeFromSuperlayer];
+    [CATransaction commit];
+}
+
 @end
 
 /******************************************************************************
index 7a84962..799e379 100644 (file)
@@ -56,6 +56,8 @@
                637D5ADC0CF6F2720073EA45 /* VLCMediaDiscoverer.m in Sources */ = {isa = PBXBuildFile; fileRef = 637D5ADB0CF6F2720073EA45 /* VLCMediaDiscoverer.m */; };
                6384FD080D0DBA20005EB1F7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6384FD070D0DBA20005EB1F7 /* QuartzCore.framework */; };
                8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
+               A7A0CEA40D2EF13000F2C039 /* VLCVideoCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A0CEA20D2EF13000F2C039 /* VLCVideoCommon.h */; };
+               A7A0CEA50D2EF13000F2C039 /* VLCVideoCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = A7A0CEA30D2EF13000F2C039 /* VLCVideoCommon.m */; };
                EF7311900CB5797B009473B4 /* VLCAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = EF73118E0CB5797B009473B4 /* VLCAudio.h */; settings = {ATTRIBUTES = (Public, ); }; };
                EF7311910CB5797B009473B4 /* VLCAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = EF73118F0CB5797B009473B4 /* VLCAudio.m */; };
                EF78BD100CAEEEC300354E6E /* VLCEventManager.h in Headers */ = {isa = PBXBuildFile; fileRef = EF78BD0D0CAEEEC300354E6E /* VLCEventManager.h */; settings = {ATTRIBUTES = (); }; };
                637D5ADB0CF6F2720073EA45 /* VLCMediaDiscoverer.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VLCMediaDiscoverer.m; sourceTree = "<group>"; };
                6384FD070D0DBA20005EB1F7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
                8DC2EF5B0486A6940098B216 /* VLC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = VLC.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               A7A0CEA20D2EF13000F2C039 /* VLCVideoCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCVideoCommon.h; path = Internal/VLCVideoCommon.h; sourceTree = "<group>"; };
+               A7A0CEA30D2EF13000F2C039 /* VLCVideoCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCVideoCommon.m; sourceTree = "<group>"; };
                D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
                EF73118E0CB5797B009473B4 /* VLCAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCAudio.h; path = Public/VLCAudio.h; sourceTree = "<group>"; };
                EF73118F0CB5797B009473B4 /* VLCAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCAudio.m; sourceTree = "<group>"; };
                                6303C4390CF45CAE0000ECC8 /* VLCMediaListAspect.m */,
                                EF8BB8CF0CAFA8D80038A613 /* VLCMediaPlayer.m */,
                                EF78BD400CAEEFF600354E6E /* VLCMediaLibrary.m */,
+                               A7A0CEA30D2EF13000F2C039 /* VLCVideoCommon.m */,
                                6341FCB00D2C0936002A97B7 /* VLCVideoLayer.m */,
                                EF78BD450CAEEFF600354E6E /* VLCVideoView.m */,
                                EF78BD440CAEEFF600354E6E /* VLCTime.m */,
                                6303C43B0CF45CC30000ECC8 /* VLCMediaListAspect.h */,
                                EF8BB8CE0CAFA8D80038A613 /* VLCMediaPlayer.h */,
                                EF78BD150CAEEEE700354E6E /* VLCMediaLibrary.h */,
+                               A7A0CEA20D2EF13000F2C039 /* VLCVideoCommon.h */,
                                6341FCAE0D2C0929002A97B7 /* VLCVideoLayer.h */,
                                EF78BD1A0CAEEEE700354E6E /* VLCVideoView.h */,
                                EF78BD190CAEEEE700354E6E /* VLCTime.h */,
                                637D5ABD0CF6F2650073EA45 /* VLCMediaDiscoverer.h in Headers */,
                                6341FCAF0D2C0929002A97B7 /* VLCVideoLayer.h in Headers */,
                                637CFB940D2D280900A041B6 /* VLCLibrary.h in Headers */,
+                               A7A0CEA40D2EF13000F2C039 /* VLCVideoCommon.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                6303C43A0CF45CAE0000ECC8 /* VLCMediaListAspect.m in Sources */,
                                637D5ADC0CF6F2720073EA45 /* VLCMediaDiscoverer.m in Sources */,
                                6341FCB10D2C0936002A97B7 /* VLCVideoLayer.m in Sources */,
+                               A7A0CEA50D2EF13000F2C039 /* VLCVideoCommon.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index eae27af..78d39b0 100644 (file)
@@ -241,13 +241,7 @@ static void End( vout_thread_t *p_vout )
 
     p_vout->p_sys->b_frame_available = VLC_FALSE;
 
-    [CATransaction performSelectorOnMainThread:@selector(begin)
-                    withObject:nil waitUntilDone:YES];
-
-    [p_sys->o_layer performSelectorOnMainThread:@selector(removeFromSuperlayer)
-                    withObject:nil waitUntilDone:YES];
-    [CATransaction performSelectorOnMainThread:@selector(commit)
-                    withObject:nil waitUntilDone:YES];
+    [p_vout->p_sys->o_cocoa_container performSelectorOnMainThread:@selector(removeVoutLayer:) withObject:p_vout->p_sys->o_layer waitUntilDone:YES];
 
     // Should be done automatically
     [p_sys->o_layer release];
@@ -314,6 +308,8 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
             p_sys->i_index = i_new_index;
             p_pic->p->p_pixels = p_sys->pp_buffer[p_sys->i_index];
             CGLUnlockContext(p_sys->glContext);
+            
+            p_sys->b_frame_available = VLC_TRUE;
         }
     }
 
@@ -327,11 +323,9 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
 static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic )
 {
     vout_sys_t *p_sys = p_vout->p_sys;
-
-    [p_sys->o_layer performSelectorOnMainThread:@selector(setNeedsDisplay)
-                    withObject:nil waitUntilDone:NO];
-
-    p_sys->b_frame_available = VLC_TRUE;
+    
+    [p_sys->o_layer performSelectorOnMainThread:@selector(display)
+                    withObject:nil waitUntilDone:YES];
 }
 
 /*****************************************************************************
@@ -466,8 +460,6 @@ static int InitTextures( vout_thread_t *p_vout )
     glFlush();
 
     CGLUnlockContext( glContext );
-
-    p_vout->p_sys->b_frame_available = VLC_FALSE;
 }
 
 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat