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
This commit is contained in:
tkchin@webrtc.org
2014-05-19 23:26:01 +00:00
parent 7ca1edb31d
commit 1732a591e7
20 changed files with 934 additions and 344 deletions

View File

@@ -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."];

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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 @@ enum {
- (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

View File

@@ -70,8 +70,6 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>