Add a UIView for rendering a video track.

RTCEAGLVideoView provides functionality to render a supplied RTCVideoTrack using OpenGLES2.

R=fischman@webrtc.org
BUG=3188

Review URL: https://webrtc-codereview.appspot.com/12489004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6192 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/examples/ios/AppRTCDemo/APPRTCAppDelegate.m b/talk/examples/ios/AppRTCDemo/APPRTCAppDelegate.m
index cc33f03..87d1f53 100644
--- a/talk/examples/ios/AppRTCDemo/APPRTCAppDelegate.m
+++ b/talk/examples/ios/AppRTCDemo/APPRTCAppDelegate.m
@@ -30,6 +30,7 @@
 #import "APPRTCAppDelegate.h"
 
 #import "APPRTCViewController.h"
+#import "RTCEAGLVideoView.h"
 #import "RTCICECandidate.h"
 #import "RTCICEServer.h"
 #import "RTCMediaConstraints.h"
@@ -43,13 +44,12 @@
 #import "RTCVideoRenderer.h"
 #import "RTCVideoCapturer.h"
 #import "RTCVideoTrack.h"
-#import "APPRTCVideoView.h"
 
 @interface PCObserver : NSObject<RTCPeerConnectionDelegate>
 
 - (id)initWithDelegate:(id<APPRTCSendMessage>)delegate;
 
-@property(nonatomic, strong) APPRTCVideoView* videoView;
+@property(nonatomic, strong) RTCEAGLVideoView* videoView;
 
 @end
 
@@ -89,8 +89,7 @@
       NSAssert([stream.videoTracks count] <= 1,
                @"Expected at most 1 video stream");
       if ([stream.videoTracks count] != 0) {
-        [self.videoView
-            renderVideoTrackInterface:[stream.videoTracks objectAtIndex:0]];
+        self.videoView.videoTrack = stream.videoTracks[0];
       }
   });
 }
@@ -291,13 +290,12 @@
   if (localVideoTrack) {
     [lms addVideoTrack:localVideoTrack];
   }
+  self.viewController.localVideoView.videoTrack = localVideoTrack;
+#else
+  self.viewController.localVideoView.hidden = YES;
 #endif
 
-  [self.viewController.localVideoView
-      renderVideoTrackInterface:localVideoTrack];
-
   self.pcObserver.videoView = self.viewController.remoteVideoView;
-
   [lms addAudioTrack:[self.peerConnectionFactory audioTrackWithID:@"ARDAMSa0"]];
   [self.peerConnection addStream:lms constraints:constraints];
   [self displayLogMessage:@"onICEServers - added local stream."];
diff --git a/talk/examples/ios/AppRTCDemo/APPRTCVideoView.h b/talk/examples/ios/AppRTCDemo/APPRTCVideoView.h
deleted file mode 100644
index 238798e..0000000
--- a/talk/examples/ios/AppRTCDemo/APPRTCVideoView.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * libjingle
- * Copyright 2013, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import <UIKit/UIKit.h>
-
-@class RTCVideoTrack;
-
-// This class encapsulates VideoRenderIosView.
-@interface APPRTCVideoView : UIView
-
-// Property to get/set required video orientation.
-@property(nonatomic, assign) UIInterfaceOrientation videoOrientation;
-// Specifies whether the object represents a local or remote video stream.
-@property(nonatomic, assign) BOOL isRemote;
-
-// Sets up the underlying renderer and track objects.
-- (void)renderVideoTrackInterface:(RTCVideoTrack*)track;
-
-@end
diff --git a/talk/examples/ios/AppRTCDemo/APPRTCVideoView.m b/talk/examples/ios/AppRTCDemo/APPRTCVideoView.m
deleted file mode 100644
index 23466b6..0000000
--- a/talk/examples/ios/AppRTCDemo/APPRTCVideoView.m
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * libjingle
- * Copyright 2013, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This APPRTCVideoView must be initialzed and added to a View to get
- * either the local or remote video stream rendered.
- * It is a view itself and it encapsulates
- * an object of VideoRenderIosView and UIActivityIndicatorView.
- * Both of the views will get resized as per the frame of their parent.
- */
-
-#import "APPRTCVideoView.h"
-
-#import "RTCVideoRenderer.h"
-#import "RTCVideoTrack.h"
-
-@interface APPRTCVideoView () {
-  RTCVideoTrack* _track;
-  RTCVideoRenderer* _renderer;
-}
-
-@property(nonatomic, weak) UIView* renderView;
-@property(nonatomic, weak) UIActivityIndicatorView* activityView;
-
-@end
-
-@implementation APPRTCVideoView
-
-@synthesize videoOrientation = _videoOrientation;
-
-- (void)layoutSubviews {
-  [super layoutSubviews];
-  if (!_renderer) {
-    // Left-right (mirror) flip the remote view.
-    CGAffineTransform xform =
-        CGAffineTransformMakeScale(self.isRemote ? -1 : 1, 1);
-    // TODO(fischman): why is this rotate (vertical+horizontal flip) needed?!?
-    xform = CGAffineTransformRotate(xform, M_PI);
-    // TODO(fischman): ensure back-camera flip is correct in all orientations,
-    // when back-camera support is added.
-    [self setTransform:xform];
-    _renderer = [[RTCVideoRenderer alloc] initWithView:self];
-  }
-}
-
-- (void)renderVideoTrackInterface:(RTCVideoTrack*)videoTrack {
-  [_track removeRenderer:_renderer];
-  [_renderer stop];
-
-  _track = videoTrack;
-
-  if (_track) {
-    [_track addRenderer:_renderer];
-    [_renderer start];
-  }
-}
-
-@end
diff --git a/talk/examples/ios/AppRTCDemo/APPRTCViewController.h b/talk/examples/ios/AppRTCDemo/APPRTCViewController.h
index f5fcee4..1737a13 100644
--- a/talk/examples/ios/AppRTCDemo/APPRTCViewController.h
+++ b/talk/examples/ios/AppRTCDemo/APPRTCViewController.h
@@ -27,7 +27,7 @@
 
 #import <UIKit/UIKit.h>
 
-@class APPRTCVideoView;
+@class RTCEAGLVideoView;
 
 // The view controller that is displayed when AppRTCDemo is loaded.
 @interface APPRTCViewController : UIViewController<UITextFieldDelegate>
@@ -37,8 +37,8 @@
 @property(weak, nonatomic) IBOutlet UITextView* logView;
 @property(weak, nonatomic) IBOutlet UIView* blackView;
 
-@property(nonatomic, strong) APPRTCVideoView* remoteVideoView;
-@property(nonatomic, strong) APPRTCVideoView* localVideoView;
+@property(nonatomic, strong) RTCEAGLVideoView* localVideoView;
+@property(nonatomic, strong) RTCEAGLVideoView* remoteVideoView;
 
 - (void)displayText:(NSString*)text;
 - (void)resetUI;
diff --git a/talk/examples/ios/AppRTCDemo/APPRTCViewController.m b/talk/examples/ios/AppRTCDemo/APPRTCViewController.m
index 0ac9282..bdd8b50 100644
--- a/talk/examples/ios/AppRTCDemo/APPRTCViewController.m
+++ b/talk/examples/ios/AppRTCDemo/APPRTCViewController.m
@@ -27,12 +27,11 @@
 
 #import "APPRTCViewController.h"
 
-#import "APPRTCVideoView.h"
+#import <AVFoundation/AVFoundation.h>
+#import "RTCEAGLVideoView.h"
 
 @interface APPRTCViewController ()
-
 @property(nonatomic, assign) UIInterfaceOrientation statusBarOrientation;
-
 @end
 
 @implementation APPRTCViewController
@@ -75,12 +74,10 @@
   self.logView.text = nil;
   self.blackView.hidden = YES;
 
-  [_remoteVideoView renderVideoTrackInterface:nil];
-  [_remoteVideoView removeFromSuperview];
+  [self.remoteVideoView removeFromSuperview];
   self.remoteVideoView = nil;
 
-  [_localVideoView renderVideoTrackInterface:nil];
-  [_localVideoView removeFromSuperview];
+  [self.localVideoView removeFromSuperview];
   self.localVideoView = nil;
 }
 
@@ -97,46 +94,29 @@
 - (void)setupCaptureSession {
   self.blackView.hidden = NO;
 
-  CGRect frame =
-      CGRectMake((self.blackView.bounds.size.width - kRemoteVideoWidth) / 2,
-                 (self.blackView.bounds.size.height - kRemoteVideoHeight) / 2,
-                 kRemoteVideoWidth,
-                 kRemoteVideoHeight);
-  APPRTCVideoView* videoView = [[APPRTCVideoView alloc] initWithFrame:frame];
-  videoView.isRemote = TRUE;
+  CGSize videoSize =
+        CGSizeMake(kRemoteVideoWidth, kRemoteVideoHeight);
+  CGRect remoteVideoFrame =
+      AVMakeRectWithAspectRatioInsideRect(videoSize,
+                                          self.blackView.bounds);
+  CGRect localVideoFrame = remoteVideoFrame;
+  // TODO(tkchin): use video dimensions from incoming video stream
+  // and handle rotation.
+  localVideoFrame.size.width = remoteVideoFrame.size.height / 4;
+  localVideoFrame.size.height = remoteVideoFrame.size.width / 4;
+  localVideoFrame.origin.x = CGRectGetMaxX(remoteVideoFrame)
+      - localVideoFrame.size.width - kLocalViewPadding;
+  localVideoFrame.origin.y = CGRectGetMaxY(remoteVideoFrame)
+      - localVideoFrame.size.height - kLocalViewPadding;
 
-  [self.blackView addSubview:videoView];
-  videoView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
-                               UIViewAutoresizingFlexibleRightMargin |
-                               UIViewAutoresizingFlexibleBottomMargin |
-                               UIViewAutoresizingFlexibleTopMargin;
-  videoView.translatesAutoresizingMaskIntoConstraints = YES;
-  _remoteVideoView = videoView;
+  self.remoteVideoView =
+      [[RTCEAGLVideoView alloc] initWithFrame:remoteVideoFrame];
+  [self.blackView addSubview:self.remoteVideoView];
+  self.remoteVideoView.transform = CGAffineTransformMakeScale(-1, 1);
 
-  CGSize screenSize = [[UIScreen mainScreen] bounds].size;
-  CGFloat localVideoViewWidth =
-      UIInterfaceOrientationIsPortrait(self.statusBarOrientation)
-          ? screenSize.width / 4
-          : screenSize.height / 4;
-  CGFloat localVideoViewHeight =
-      UIInterfaceOrientationIsPortrait(self.statusBarOrientation)
-          ? screenSize.height / 4
-          : screenSize.width / 4;
-  frame = CGRectMake(self.blackView.bounds.size.width - localVideoViewWidth -
-                         kLocalViewPadding,
-                     kLocalViewPadding,
-                     localVideoViewWidth,
-                     localVideoViewHeight);
-  videoView = [[APPRTCVideoView alloc] initWithFrame:frame];
-  videoView.isRemote = FALSE;
-
-  [self.blackView addSubview:videoView];
-  videoView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
-                               UIViewAutoresizingFlexibleBottomMargin |
-                               UIViewAutoresizingFlexibleHeight |
-                               UIViewAutoresizingFlexibleWidth;
-  videoView.translatesAutoresizingMaskIntoConstraints = YES;
-  _localVideoView = videoView;
+  self.localVideoView =
+      [[RTCEAGLVideoView alloc] initWithFrame:localVideoFrame];
+  [self.blackView addSubview:self.localVideoView];
 }
 
 #pragma mark - UITextFieldDelegate
diff --git a/talk/examples/ios/AppRTCDemo/Info.plist b/talk/examples/ios/AppRTCDemo/Info.plist
index 72504aa..a32be86 100644
--- a/talk/examples/ios/AppRTCDemo/Info.plist
+++ b/talk/examples/ios/AppRTCDemo/Info.plist
@@ -70,8 +70,6 @@
         <key>UISupportedInterfaceOrientations</key>
         <array>
                 <string>UIInterfaceOrientationPortrait</string>
-                <string>UIInterfaceOrientationLandscapeLeft</string>
-                <string>UIInterfaceOrientationLandscapeRight</string>
         </array>
 </dict>
 </plist>