From 562748d2a4b6bda442626b57948ea01ebc358b11 Mon Sep 17 00:00:00 2001 From: "mcasas@webrtc.org" Date: Tue, 4 Nov 2014 17:26:22 +0000 Subject: AppRTCDemoActivity: use differnet Themes for different API levels The current AndroidManifest.xml hardcodes a Theme that is only available in Android L or later (Material). To maintain backwards compatibility, and for better App style, create a single Theme/Style and define it for different APIs. I tested this in two Nexus %, one with prerelease L and another with a KK 4.4.2 and the Theme is indeed automagically updated :) Note that this is compatible with https://webrtc-codereview.appspot.com/26979004/ R=glaznev@webrtc.org Review URL: https://webrtc-codereview.appspot.com/26019004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7619 4adac7df-926f-26a2-2b94-8c16560cd09d --- examples/android/AndroidManifest.xml | 4 ++-- examples/android/res/values-v21/styles.xml | 8 ++++++++ examples/android/res/values/styles.xml | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 examples/android/res/values-v21/styles.xml create mode 100644 examples/android/res/values/styles.xml diff --git a/examples/android/AndroidManifest.xml b/examples/android/AndroidManifest.xml index 30fd46c..e24942a 100644 --- a/examples/android/AndroidManifest.xml +++ b/examples/android/AndroidManifest.xml @@ -7,7 +7,7 @@ - + @@ -43,7 +43,7 @@ android:label="@string/app_name" android:screenOrientation="fullUser" android:configChanges="orientation|screenSize" - android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + android:theme="@style/AppRTCDemoActivityTheme"> diff --git a/examples/android/res/values-v21/styles.xml b/examples/android/res/values-v21/styles.xml new file mode 100644 index 0000000..95f1ac6 --- /dev/null +++ b/examples/android/res/values-v21/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/examples/android/res/values/styles.xml b/examples/android/res/values/styles.xml new file mode 100644 index 0000000..7f809a6 --- /dev/null +++ b/examples/android/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + -- cgit v1.2.3 From 1fc1bd09ab4a988010edc53715d0e9991f876dc1 Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Tue, 4 Nov 2014 21:48:54 +0000 Subject: (Auto)update libjingle 79169148-> 79192489 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7624 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/media/webrtc/webrtcvideoengine.h b/media/webrtc/webrtcvideoengine.h index cc81ee9..2966511 100644 --- a/media/webrtc/webrtcvideoengine.h +++ b/media/webrtc/webrtcvideoengine.h @@ -177,6 +177,10 @@ class WebRtcVideoEngine : public sigslot::has_slots<>, rtc::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); } protected: + bool initialized() const { + return initialized_; + } + // When a video processor registers with the engine. // SignalMediaFrame will be invoked for every video frame. // See videoprocessor.h for param reference. -- cgit v1.2.3 From e889fa57d94294d2f1acceed57d72b8896ca1d37 Mon Sep 17 00:00:00 2001 From: "tkchin@webrtc.org" Date: Tue, 4 Nov 2014 23:06:15 +0000 Subject: Cleanup RTCVideoRenderer interface. RTCVideoRenderer should be a protocol not a class. This change includes an adapter for use with the C++ apis. The video views have been refactored to implement that protocol. BUG=3795 R=glaznev@webrtc.org Review URL: https://webrtc-codereview.appspot.com/23279004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7626 4adac7df-926f-26a2-2b94-8c16560cd09d --- app/webrtc/objc/RTCEAGLVideoView+Internal.h | 36 ---------- app/webrtc/objc/RTCEAGLVideoView.m | 58 ++++++---------- app/webrtc/objc/RTCI420Frame.mm | 4 ++ app/webrtc/objc/RTCMediaStream.mm | 5 +- app/webrtc/objc/RTCNSGLVideoView.m | 46 ++----------- app/webrtc/objc/RTCVideoRenderer+Internal.h | 36 ---------- app/webrtc/objc/RTCVideoRenderer.mm | 79 ---------------------- app/webrtc/objc/RTCVideoRendererAdapter.h | 40 +++++++++++ app/webrtc/objc/RTCVideoRendererAdapter.mm | 75 ++++++++++++++++++++ app/webrtc/objc/RTCVideoTrack+Internal.h | 4 +- app/webrtc/objc/RTCVideoTrack.mm | 47 +++++++------ app/webrtc/objc/public/RTCEAGLVideoView.h | 7 +- app/webrtc/objc/public/RTCI420Frame.h | 2 + app/webrtc/objc/public/RTCNSGLVideoView.h | 5 +- app/webrtc/objc/public/RTCVideoRenderer.h | 27 +------- app/webrtc/objc/public/RTCVideoTrack.h | 9 +-- app/webrtc/objctests/RTCPeerConnectionTest.mm | 13 +++- .../objc/AppRTCDemo/ios/APPRTCViewController.m | 21 ++++-- .../objc/AppRTCDemo/mac/APPRTCViewController.m | 12 +++- libjingle.gyp | 5 +- 20 files changed, 230 insertions(+), 301 deletions(-) delete mode 100644 app/webrtc/objc/RTCEAGLVideoView+Internal.h delete mode 100644 app/webrtc/objc/RTCVideoRenderer+Internal.h delete mode 100644 app/webrtc/objc/RTCVideoRenderer.mm create mode 100644 app/webrtc/objc/RTCVideoRendererAdapter.h create mode 100644 app/webrtc/objc/RTCVideoRendererAdapter.mm diff --git a/app/webrtc/objc/RTCEAGLVideoView+Internal.h b/app/webrtc/objc/RTCEAGLVideoView+Internal.h deleted file mode 100644 index 10df2e3..0000000 --- a/app/webrtc/objc/RTCEAGLVideoView+Internal.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * libjingle - * Copyright 2014, 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 - -#import "RTCEAGLVideoView.h" -#import "RTCVideoRenderer.h" - -// TODO(tkchin): Move declaration to implementation file. Exposed here in order -// to support deprecated methods in RTCVideoRenderer. -@interface RTCEAGLVideoView (Internal) -@end diff --git a/app/webrtc/objc/RTCEAGLVideoView.m b/app/webrtc/objc/RTCEAGLVideoView.m index faacef6..c55c87e 100644 --- a/app/webrtc/objc/RTCEAGLVideoView.m +++ b/app/webrtc/objc/RTCEAGLVideoView.m @@ -29,13 +29,12 @@ #error "This file requires ARC support." #endif -#import "RTCEAGLVideoView+Internal.h" +#import "RTCEAGLVideoView.h" #import +#import "RTCI420Frame.h" #import "RTCOpenGLVideoRenderer.h" -#import "RTCVideoRenderer.h" -#import "RTCVideoTrack.h" // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen // refreshes, which should be 30fps. We wrap the display link in order to avoid @@ -105,7 +104,6 @@ RTCDisplayLinkTimer* _timer; GLKView* _glkView; RTCOpenGLVideoRenderer* _glRenderer; - RTCVideoRenderer* _videoRenderer; } - (instancetype)initWithFrame:(CGRect)frame { @@ -152,7 +150,6 @@ // GLKViewDelegate method implemented below. [strongSelf.glkView setNeedsDisplay]; }]; - _videoRenderer = [[RTCVideoRenderer alloc] initWithDelegate:self]; [self setupGL]; } return self; @@ -168,18 +165,6 @@ [_timer invalidate]; } -- (void)setVideoTrack:(RTCVideoTrack*)videoTrack { - if (_videoTrack == videoTrack) { - return; - } - [_videoTrack removeRenderer:_videoRenderer]; - self.i420Frame = nil; - _videoTrack = videoTrack; - [_videoTrack addRenderer:_videoRenderer]; - // TODO(tkchin): potentially handle changes in track state - e.g. render - // black if track fails. -} - #pragma mark - UIView - (void)layoutSubviews { @@ -197,14 +182,31 @@ [_glRenderer drawFrame:self.i420Frame]; } +#pragma mark - RTCVideoRenderer + +// These methods may be called on non-main thread. +- (void)setSize:(CGSize)size { + __weak RTCEAGLVideoView* weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + RTCEAGLVideoView* strongSelf = weakSelf; + [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size]; + }); +} + +- (void)renderFrame:(RTCI420Frame*)frame { + self.i420Frame = frame; +} + #pragma mark - Private - (void)setupGL { + self.i420Frame = nil; [_glRenderer setupGL]; _timer.isPaused = NO; } - (void)teardownGL { + self.i420Frame = nil; _timer.isPaused = YES; [_glkView deleteDrawable]; [_glRenderer teardownGL]; @@ -219,25 +221,3 @@ } @end - -@implementation RTCEAGLVideoView (Internal) - -#pragma mark - RTCVideoRendererDelegate - -// These methods are called when the video track has frame information to -// provide. This occurs on non-main thread. -- (void)renderer:(RTCVideoRenderer*)renderer - didSetSize:(CGSize)size { - __weak RTCEAGLVideoView* weakSelf = self; - dispatch_async(dispatch_get_main_queue(), ^{ - RTCEAGLVideoView* strongSelf = weakSelf; - [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size]; - }); -} - -- (void)renderer:(RTCVideoRenderer*)renderer - didReceiveFrame:(RTCI420Frame*)frame { - self.i420Frame = frame; -} - -@end diff --git a/app/webrtc/objc/RTCI420Frame.mm b/app/webrtc/objc/RTCI420Frame.mm index 0b50691..9c394e5 100644 --- a/app/webrtc/objc/RTCI420Frame.mm +++ b/app/webrtc/objc/RTCI420Frame.mm @@ -78,6 +78,10 @@ return _videoFrame->GetVPitch(); } +- (BOOL)makeExclusive { + return _videoFrame->MakeExclusive(); +} + @end @implementation RTCI420Frame (Internal) diff --git a/app/webrtc/objc/RTCMediaStream.mm b/app/webrtc/objc/RTCMediaStream.mm index 27d20b8..a72508a 100644 --- a/app/webrtc/objc/RTCMediaStream.mm +++ b/app/webrtc/objc/RTCMediaStream.mm @@ -71,7 +71,7 @@ } - (BOOL)addVideoTrack:(RTCVideoTrack*)track { - if (self.mediaStream->AddTrack(track.videoTrack)) { + if (self.mediaStream->AddTrack(track.nativeVideoTrack)) { [_videoTracks addObject:track]; return YES; } @@ -93,7 +93,8 @@ NSUInteger index = [_videoTracks indexOfObjectIdenticalTo:track]; NSAssert(index != NSNotFound, @"|removeAudioTrack| called on unexpected RTCVideoTrack"); - if (index != NSNotFound && self.mediaStream->RemoveTrack(track.videoTrack)) { + if (index != NSNotFound && + self.mediaStream->RemoveTrack(track.nativeVideoTrack)) { [_videoTracks removeObjectAtIndex:index]; return YES; } diff --git a/app/webrtc/objc/RTCNSGLVideoView.m b/app/webrtc/objc/RTCNSGLVideoView.m index 292e792..7aa4a11 100644 --- a/app/webrtc/objc/RTCNSGLVideoView.m +++ b/app/webrtc/objc/RTCNSGLVideoView.m @@ -33,10 +33,10 @@ #import #import +#import "RTCI420Frame.h" #import "RTCOpenGLVideoRenderer.h" -#import "RTCVideoRenderer.h" -@interface RTCNSGLVideoView () +@interface RTCNSGLVideoView () // |i420Frame| is set when we receive a frame from a worker thread and is read // from the display link callback so atomicity is required. @property(atomic, strong) RTCI420Frame* i420Frame; @@ -57,15 +57,6 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, @implementation RTCNSGLVideoView { CVDisplayLinkRef _displayLink; - RTCVideoRenderer* _videoRenderer; -} - -- (instancetype)initWithFrame:(NSRect)frame - pixelFormat:(NSOpenGLPixelFormat*)format { - if (self = [super initWithFrame:frame pixelFormat:format]) { - _videoRenderer = [[RTCVideoRenderer alloc] initWithDelegate:self]; - } - return self; } - (void)dealloc { @@ -109,37 +100,16 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, [super clearGLContext]; } -- (void)setVideoTrack:(RTCVideoTrack*)videoTrack { - if (_videoTrack == videoTrack) { - return; - } - if (_videoTrack) { - [_videoTrack removeRenderer:_videoRenderer]; - CVDisplayLinkStop(_displayLink); - // Clear contents. - self.i420Frame = nil; - [self drawFrame]; - } - _videoTrack = videoTrack; - if (_videoTrack) { - [_videoTrack addRenderer:_videoRenderer]; - CVDisplayLinkStart(_displayLink); - } -} - -#pragma mark - RTCVideoRendererDelegate +#pragma mark - RTCVideoRenderer -// These methods are called when the video track has frame information to -// provide. This occurs on non-main thread. -- (void)renderer:(RTCVideoRenderer*)renderer - didSetSize:(CGSize)size { +// These methods may be called on non-main thread. +- (void)setSize:(CGSize)size { dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate videoView:self didChangeVideoSize:size]; }); } -- (void)renderer:(RTCVideoRenderer*)renderer - didReceiveFrame:(RTCI420Frame*)frame { +- (void)renderFrame:(RTCI420Frame*)frame { self.i420Frame = frame; } @@ -174,9 +144,7 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj]; CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( _displayLink, cglContext, cglPixelFormat); - if (_videoTrack) { - CVDisplayLinkStart(_displayLink); - } + CVDisplayLinkStart(_displayLink); } - (void)teardownDisplayLink { diff --git a/app/webrtc/objc/RTCVideoRenderer+Internal.h b/app/webrtc/objc/RTCVideoRenderer+Internal.h deleted file mode 100644 index 22e445c..0000000 --- a/app/webrtc/objc/RTCVideoRenderer+Internal.h +++ /dev/null @@ -1,36 +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 "RTCVideoRenderer.h" - -#include "talk/app/webrtc/mediastreaminterface.h" - -@interface RTCVideoRenderer (Internal) - -@property(nonatomic, readonly) webrtc::VideoRendererInterface* videoRenderer; - -@end diff --git a/app/webrtc/objc/RTCVideoRenderer.mm b/app/webrtc/objc/RTCVideoRenderer.mm deleted file mode 100644 index 4cfe43a..0000000 --- a/app/webrtc/objc/RTCVideoRenderer.mm +++ /dev/null @@ -1,79 +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. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "RTCVideoRenderer+Internal.h" -#import "RTCI420Frame+Internal.h" - -namespace webrtc { - -class RTCVideoRendererAdapter : public VideoRendererInterface { - public: - RTCVideoRendererAdapter(RTCVideoRenderer* renderer) { _renderer = renderer; } - - virtual void SetSize(int width, int height) OVERRIDE { - [_renderer.delegate renderer:_renderer - didSetSize:CGSizeMake(width, height)]; - } - - virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE { - if (!_renderer.delegate) { - return; - } - RTCI420Frame* i420Frame = [[RTCI420Frame alloc] initWithVideoFrame:frame]; - [_renderer.delegate renderer:_renderer didReceiveFrame:i420Frame]; - } - - private: - __weak RTCVideoRenderer* _renderer; -}; -} - -@implementation RTCVideoRenderer { - rtc::scoped_ptr _adapter; -} - -- (instancetype)initWithDelegate:(id)delegate { - if (self = [super init]) { - _delegate = delegate; - _adapter.reset(new webrtc::RTCVideoRendererAdapter(self)); - } - return self; -} - -@end - -@implementation RTCVideoRenderer (Internal) - -- (webrtc::VideoRendererInterface*)videoRenderer { - return _adapter.get(); -} - -@end diff --git a/app/webrtc/objc/RTCVideoRendererAdapter.h b/app/webrtc/objc/RTCVideoRendererAdapter.h new file mode 100644 index 0000000..faf0906 --- /dev/null +++ b/app/webrtc/objc/RTCVideoRendererAdapter.h @@ -0,0 +1,40 @@ +/* + * 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 "RTCVideoRenderer.h" + +#include "talk/app/webrtc/mediastreaminterface.h" + +@interface RTCVideoRendererAdapter : NSObject + +@property(nonatomic, readonly) id videoRenderer; +@property(nonatomic, readonly) + webrtc::VideoRendererInterface* nativeVideoRenderer; + +- (instancetype)initWithVideoRenderer:(id)videoRenderer; + +@end diff --git a/app/webrtc/objc/RTCVideoRendererAdapter.mm b/app/webrtc/objc/RTCVideoRendererAdapter.mm new file mode 100644 index 0000000..e29faad --- /dev/null +++ b/app/webrtc/objc/RTCVideoRendererAdapter.mm @@ -0,0 +1,75 @@ +/* + * 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. + */ + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "RTCVideoRendererAdapter.h" +#import "RTCI420Frame+Internal.h" + +namespace webrtc { + +class RTCVideoRendererNativeAdapter : public VideoRendererInterface { + public: + RTCVideoRendererNativeAdapter(RTCVideoRendererAdapter* adapter) { + _adapter = adapter; + } + + virtual void SetSize(int width, int height) OVERRIDE { + [_adapter.videoRenderer setSize:CGSizeMake(width, height)]; + } + + virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE { + RTCI420Frame* i420Frame = [[RTCI420Frame alloc] initWithVideoFrame:frame]; + [_adapter.videoRenderer renderFrame:i420Frame]; + } + + private: + __weak RTCVideoRendererAdapter* _adapter; +}; +} + +@implementation RTCVideoRendererAdapter { + id _videoRenderer; + rtc::scoped_ptr _adapter; +} + +- (instancetype)initWithVideoRenderer:(id)videoRenderer { + NSParameterAssert(videoRenderer); + if (self = [super init]) { + _videoRenderer = videoRenderer; + _adapter.reset(new webrtc::RTCVideoRendererNativeAdapter(self)); + } + return self; +} + +- (webrtc::VideoRendererInterface*)nativeVideoRenderer { + return _adapter.get(); +} + +@end diff --git a/app/webrtc/objc/RTCVideoTrack+Internal.h b/app/webrtc/objc/RTCVideoTrack+Internal.h index 03c8f95..5f267ac 100644 --- a/app/webrtc/objc/RTCVideoTrack+Internal.h +++ b/app/webrtc/objc/RTCVideoTrack+Internal.h @@ -34,7 +34,7 @@ @interface RTCVideoTrack (Internal) -@property(nonatomic, assign, readonly) - rtc::scoped_refptr videoTrack; +@property(nonatomic, readonly) + rtc::scoped_refptr nativeVideoTrack; @end diff --git a/app/webrtc/objc/RTCVideoTrack.mm b/app/webrtc/objc/RTCVideoTrack.mm index beebde0..959bc6d 100644 --- a/app/webrtc/objc/RTCVideoTrack.mm +++ b/app/webrtc/objc/RTCVideoTrack.mm @@ -32,46 +32,55 @@ #import "RTCVideoTrack+Internal.h" #import "RTCMediaStreamTrack+Internal.h" -#import "RTCVideoRenderer+Internal.h" +#import "RTCVideoRendererAdapter.h" @implementation RTCVideoTrack { - NSMutableArray* _rendererArray; + NSMutableArray* _adapters; } - (id)initWithMediaTrack: (rtc::scoped_refptr) mediaTrack { if (self = [super initWithMediaTrack:mediaTrack]) { - _rendererArray = [NSMutableArray array]; + _adapters = [NSMutableArray array]; } return self; } -- (void)addRenderer:(RTCVideoRenderer*)renderer { - NSAssert1(![self.renderers containsObject:renderer], - @"renderers already contains object [%@]", - [renderer description]); - [_rendererArray addObject:renderer]; - self.videoTrack->AddRenderer(renderer.videoRenderer); -} - -- (void)removeRenderer:(RTCVideoRenderer*)renderer { - NSUInteger index = [self.renderers indexOfObjectIdenticalTo:renderer]; - if (index != NSNotFound) { - [_rendererArray removeObjectAtIndex:index]; - self.videoTrack->RemoveRenderer(renderer.videoRenderer); +- (void)addRenderer:(id)renderer { + // Make sure we don't have this renderer yet. + for (RTCVideoRendererAdapter* adapter in _adapters) { + NSParameterAssert(adapter.videoRenderer != renderer); } + // Create a wrapper that provides a native pointer for us. + RTCVideoRendererAdapter* adapter = + [[RTCVideoRendererAdapter alloc] initWithVideoRenderer:renderer]; + [_adapters addObject:adapter]; + self.nativeVideoTrack->AddRenderer(adapter.nativeVideoRenderer); } -- (NSArray*)renderers { - return [_rendererArray copy]; +- (void)removeRenderer:(id)renderer { + RTCVideoRendererAdapter* adapter = nil; + NSUInteger indexToRemove = NSNotFound; + for (NSUInteger i = 0; i < _adapters.count; i++) { + adapter = _adapters[i]; + if (adapter.videoRenderer == renderer) { + indexToRemove = i; + break; + } + } + if (indexToRemove == NSNotFound) { + return; + } + self.nativeVideoTrack->RemoveRenderer(adapter.nativeVideoRenderer); + [_adapters removeObjectAtIndex:indexToRemove]; } @end @implementation RTCVideoTrack (Internal) -- (rtc::scoped_refptr)videoTrack { +- (rtc::scoped_refptr)nativeVideoTrack { return static_cast(self.mediaTrack.get()); } diff --git a/app/webrtc/objc/public/RTCEAGLVideoView.h b/app/webrtc/objc/public/RTCEAGLVideoView.h index c38799e..526175f 100644 --- a/app/webrtc/objc/public/RTCEAGLVideoView.h +++ b/app/webrtc/objc/public/RTCEAGLVideoView.h @@ -37,11 +37,10 @@ @end -@class RTCVideoTrack; -// RTCEAGLVideoView renders |videoTrack| onto itself using OpenGLES. -@interface RTCEAGLVideoView : UIView +// RTCEAGLVideoView is an RTCVideoRenderer which renders i420 frames in its +// bounds using OpenGLES 2.0. +@interface RTCEAGLVideoView : UIView -@property(nonatomic, strong) RTCVideoTrack* videoTrack; @property(nonatomic, weak) id delegate; @end diff --git a/app/webrtc/objc/public/RTCI420Frame.h b/app/webrtc/objc/public/RTCI420Frame.h index 737968c..7a8c4d4 100644 --- a/app/webrtc/objc/public/RTCI420Frame.h +++ b/app/webrtc/objc/public/RTCI420Frame.h @@ -43,6 +43,8 @@ @property(nonatomic, readonly) NSInteger uPitch; @property(nonatomic, readonly) NSInteger vPitch; +- (BOOL)makeExclusive; + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Disallow init and don't add to documentation - (id)init __attribute__(( diff --git a/app/webrtc/objc/public/RTCNSGLVideoView.h b/app/webrtc/objc/public/RTCNSGLVideoView.h index fd757cb..0af2dc5 100644 --- a/app/webrtc/objc/public/RTCNSGLVideoView.h +++ b/app/webrtc/objc/public/RTCNSGLVideoView.h @@ -31,7 +31,7 @@ #import -#import "RTCVideoTrack.h" +#import "RTCVideoRenderer.h" @class RTCNSGLVideoView; @protocol RTCNSGLVideoViewDelegate @@ -40,9 +40,8 @@ @end -@interface RTCNSGLVideoView : NSOpenGLView +@interface RTCNSGLVideoView : NSOpenGLView -@property(nonatomic, strong) RTCVideoTrack* videoTrack; @property(nonatomic, weak) id delegate; @end diff --git a/app/webrtc/objc/public/RTCVideoRenderer.h b/app/webrtc/objc/public/RTCVideoRenderer.h index 37977ce..3c2baba 100644 --- a/app/webrtc/objc/public/RTCVideoRenderer.h +++ b/app/webrtc/objc/public/RTCVideoRenderer.h @@ -31,34 +31,13 @@ #endif @class RTCI420Frame; -@class RTCVideoRenderer; -// RTCVideoRendererDelegate is a protocol for an object that must be -// implemented to get messages when rendering. -@protocol RTCVideoRendererDelegate +@protocol RTCVideoRenderer // The size of the frame. -- (void)renderer:(RTCVideoRenderer*)renderer didSetSize:(CGSize)size; +- (void)setSize:(CGSize)size; // The frame to be displayed. -- (void)renderer:(RTCVideoRenderer*)renderer - didReceiveFrame:(RTCI420Frame*)frame; - -@end - -// Interface for rendering VideoFrames from a VideoTrack -@interface RTCVideoRenderer : NSObject - -@property(nonatomic, weak) id delegate; - -// Initialize the renderer. Requires a delegate which does the actual drawing -// of frames. -- (instancetype)initWithDelegate:(id)delegate; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -// Disallow init and don't add to documentation -- (id)init __attribute__(( - unavailable("init is not a supported initializer for this class."))); -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ +- (void)renderFrame:(RTCI420Frame*)frame; @end diff --git a/app/webrtc/objc/public/RTCVideoTrack.h b/app/webrtc/objc/public/RTCVideoTrack.h index 291c923..8385b71 100644 --- a/app/webrtc/objc/public/RTCVideoTrack.h +++ b/app/webrtc/objc/public/RTCVideoTrack.h @@ -27,19 +27,16 @@ #import "RTCMediaStreamTrack.h" -@class RTCVideoRenderer; +@protocol RTCVideoRenderer; // RTCVideoTrack is an ObjectiveC wrapper for VideoTrackInterface. @interface RTCVideoTrack : RTCMediaStreamTrack -// The currently registered renderers. -@property(nonatomic, strong, readonly) NSArray *renderers; - // Register a renderer that will render all frames received on this track. -- (void)addRenderer:(RTCVideoRenderer *)renderer; +- (void)addRenderer:(id)renderer; // Deregister a renderer. -- (void)removeRenderer:(RTCVideoRenderer *)renderer; +- (void)removeRenderer:(id)renderer; #ifndef DOXYGEN_SHOULD_SKIP_THIS // Disallow init and don't add to documentation diff --git a/app/webrtc/objctests/RTCPeerConnectionTest.mm b/app/webrtc/objctests/RTCPeerConnectionTest.mm index 6c5950b..92d3c49 100644 --- a/app/webrtc/objctests/RTCPeerConnectionTest.mm +++ b/app/webrtc/objctests/RTCPeerConnectionTest.mm @@ -46,6 +46,16 @@ #error "This file requires ARC support." #endif +@interface RTCFakeRenderer : NSObject +@end + +@implementation RTCFakeRenderer + +- (void)setSize:(CGSize)size {} +- (void)renderFrame:(RTCI420Frame*)frame {} + +@end + @interface RTCPeerConnectionTest : NSObject // Returns whether the two sessions are of the same type. @@ -80,8 +90,7 @@ RTCMediaStream* localMediaStream = [factory mediaStreamWithLabel:streamLabel]; RTCVideoTrack* videoTrack = [factory videoTrackWithID:videoTrackID source:videoSource]; - RTCVideoRenderer* videoRenderer = - [[RTCVideoRenderer alloc] initWithDelegate:nil]; + RTCFakeRenderer* videoRenderer = [[RTCFakeRenderer alloc] init]; [videoTrack addRenderer:videoRenderer]; [localMediaStream addVideoTrack:videoTrack]; // Test that removal/re-add works. diff --git a/examples/objc/AppRTCDemo/ios/APPRTCViewController.m b/examples/objc/AppRTCDemo/ios/APPRTCViewController.m index 8042762..d8d9714 100644 --- a/examples/objc/AppRTCDemo/ios/APPRTCViewController.m +++ b/examples/objc/AppRTCDemo/ios/APPRTCViewController.m @@ -34,6 +34,7 @@ #import #import "APPRTCConnectionManager.h" #import "RTCEAGLVideoView.h" +#import "RTCVideoTrack.h" // Padding space for local video view with its parent. static CGFloat const kLocalViewPadding = 20; @@ -47,6 +48,8 @@ static CGFloat const kLocalViewPadding = 20; @implementation APPRTCViewController { APPRTCConnectionManager* _connectionManager; + RTCVideoTrack* _localVideoTrack; + RTCVideoTrack* _remoteVideoTrack; CGSize _localVideoSize; CGSize _remoteVideoSize; } @@ -101,13 +104,15 @@ static CGFloat const kLocalViewPadding = 20; - (void)connectionManager:(APPRTCConnectionManager*)manager didReceiveLocalVideoTrack:(RTCVideoTrack*)localVideoTrack { + _localVideoTrack = localVideoTrack; + [_localVideoTrack addRenderer:self.localVideoView]; self.localVideoView.hidden = NO; - self.localVideoView.videoTrack = localVideoTrack; } - (void)connectionManager:(APPRTCConnectionManager*)manager didReceiveRemoteVideoTrack:(RTCVideoTrack*)remoteVideoTrack { - self.remoteVideoView.videoTrack = remoteVideoTrack; + _remoteVideoTrack = remoteVideoTrack; + [_remoteVideoTrack addRenderer:self.remoteVideoView]; } - (void)connectionManagerDidReceiveHangup:(APPRTCConnectionManager*)manager { @@ -193,8 +198,16 @@ static CGFloat const kLocalViewPadding = 20; self.instructionsView.hidden = NO; self.logView.hidden = YES; self.logView.text = nil; - self.localVideoView.videoTrack = nil; - self.remoteVideoView.videoTrack = nil; + if (_localVideoTrack) { + [_localVideoTrack removeRenderer:self.localVideoView]; + _localVideoTrack = nil; + [self.localVideoView renderFrame:nil]; + } + if (_remoteVideoTrack) { + [_remoteVideoTrack removeRenderer:self.remoteVideoView]; + _remoteVideoTrack = nil; + [self.remoteVideoView renderFrame:nil]; + } self.blackView.hidden = YES; } diff --git a/examples/objc/AppRTCDemo/mac/APPRTCViewController.m b/examples/objc/AppRTCDemo/mac/APPRTCViewController.m index cf5b836..08acac9 100644 --- a/examples/objc/AppRTCDemo/mac/APPRTCViewController.m +++ b/examples/objc/AppRTCDemo/mac/APPRTCViewController.m @@ -30,6 +30,7 @@ #import #import "APPRTCConnectionManager.h" #import "RTCNSGLVideoView.h" +#import "RTCVideoTrack.h" static NSUInteger const kContentWidth = 1280; static NSUInteger const kContentHeight = 720; @@ -227,6 +228,8 @@ static NSUInteger const kLogViewHeight = 280; @implementation APPRTCViewController { APPRTCConnectionManager* _connectionManager; + RTCVideoTrack* _localVideoTrack; + RTCVideoTrack* _remoteVideoTrack; } - (instancetype)initWithNibName:(NSString*)nibName @@ -258,12 +261,13 @@ static NSUInteger const kLogViewHeight = 280; - (void)connectionManager:(APPRTCConnectionManager*)manager didReceiveLocalVideoTrack:(RTCVideoTrack*)localVideoTrack { - self.mainView.localVideoView.videoTrack = localVideoTrack; + _localVideoTrack = localVideoTrack; } - (void)connectionManager:(APPRTCConnectionManager*)manager didReceiveRemoteVideoTrack:(RTCVideoTrack*)remoteVideoTrack { - self.mainView.remoteVideoView.videoTrack = remoteVideoTrack; + _remoteVideoTrack = remoteVideoTrack; + [_remoteVideoTrack addRenderer:self.mainView.remoteVideoView]; } - (void)connectionManagerDidReceiveHangup:(APPRTCConnectionManager*)manager { @@ -305,7 +309,9 @@ static NSUInteger const kLogViewHeight = 280; } - (void)disconnect { - self.mainView.remoteVideoView.videoTrack = nil; + [_remoteVideoTrack removeRenderer:self.mainView.remoteVideoView]; + _remoteVideoTrack = nil; + [self.mainView.remoteVideoView renderFrame:nil]; [_connectionManager disconnect]; } diff --git a/libjingle.gyp b/libjingle.gyp index 803eaa3..90d1f41 100755 --- a/libjingle.gyp +++ b/libjingle.gyp @@ -204,8 +204,8 @@ 'app/webrtc/objc/RTCStatsReport.mm', 'app/webrtc/objc/RTCVideoCapturer+Internal.h', 'app/webrtc/objc/RTCVideoCapturer.mm', - 'app/webrtc/objc/RTCVideoRenderer+Internal.h', - 'app/webrtc/objc/RTCVideoRenderer.mm', + 'app/webrtc/objc/RTCVideoRendererAdapter.h', + 'app/webrtc/objc/RTCVideoRendererAdapter.mm', 'app/webrtc/objc/RTCVideoSource+Internal.h', 'app/webrtc/objc/RTCVideoSource.mm', 'app/webrtc/objc/RTCVideoTrack+Internal.h', @@ -259,7 +259,6 @@ 'conditions': [ ['OS=="ios"', { 'sources': [ - 'app/webrtc/objc/RTCEAGLVideoView+Internal.h', 'app/webrtc/objc/RTCEAGLVideoView.m', 'app/webrtc/objc/public/RTCEAGLVideoView.h', ], -- cgit v1.2.3 From 007bff38ded37774bfc1e538647be6c65088700a Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Wed, 5 Nov 2014 00:14:02 +0000 Subject: (Auto)update libjingle 79200114-> 79205306 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7627 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine.cc | 103 +++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc index 04092f3..d0ed46d 100644 --- a/media/webrtc/webrtcvideoengine.cc +++ b/media/webrtc/webrtcvideoengine.cc @@ -1987,14 +1987,21 @@ bool WebRtcVideoMediaChannel::AddSendStream(const StreamParams& sp) { SetReceiverReportSsrc(sp.first_ssrc()); } - send_channel->set_stream_params(sp); - - // Reset send codec after stream parameters changed. if (send_codec_) { - if (!SetSendCodec(send_channel, *send_codec_)) { + send_channel->SetAdaptFormat( + VideoFormatFromVieCodec(*send_codec_), + WebRtcVideoChannelSendInfo::kAdaptFormatTypeCodec); + + VideoSendParams send_params; + send_params.codec = *send_codec_; + send_params.stream = sp; + if (!SetSendParams(send_channel, send_params)) { return false; } - LogSendCodecChange("SetSendStreamFormat()"); + LogSendCodecChange("AddStream()"); + } else { + // Save the stream params for later, when we have a codec. + send_channel->set_stream_params(sp); } if (sending_) { @@ -2990,40 +2997,41 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) { VideoOptions original = options_; options_.SetAll(options); - // Set CPU options for all send channels. + // Set CPU options and codec options for all send channels. for (SendChannelMap::iterator iter = send_channels_.begin(); iter != send_channels_.end(); ++iter) { WebRtcVideoChannelSendInfo* send_channel = iter->second; send_channel->ApplyCpuOptions(options_); - } - if (send_codec_) { - webrtc::VideoCodec new_codec = *send_codec_; - - bool conference_mode_turned_off = ( - original.conference_mode.IsSet() && - options.conference_mode.IsSet() && - original.conference_mode.GetWithDefaultIfUnset(false) && - !options.conference_mode.GetWithDefaultIfUnset(false)); - if (conference_mode_turned_off) { - // This is a special case for turning conference mode off. - // Max bitrate should go back to the default maximum value instead - // of the current maximum. - new_codec.maxBitrate = kAutoBandwidth; - } + if (send_codec_) { + VideoSendParams send_params = send_channel->send_params(); + + bool conference_mode_turned_off = ( + original.conference_mode.IsSet() && + options.conference_mode.IsSet() && + original.conference_mode.GetWithDefaultIfUnset(false) && + !options.conference_mode.GetWithDefaultIfUnset(false)); + if (conference_mode_turned_off) { + // This is a special case for turning conference mode off. + // Max bitrate should go back to the default maximum value instead + // of the current maximum. + send_params.codec.maxBitrate = kAutoBandwidth; + } - // TODO(pthatcher): Remove this. We don't need 4 ways to set bitrates. - int new_start_bitrate; - if (options.video_start_bitrate.Get(&new_start_bitrate)) { - new_codec.startBitrate = new_start_bitrate; - } + // TODO(pthatcher): Remove this. We don't need 4 ways to set bitrates. + int new_start_bitrate; + if (options.video_start_bitrate.Get(&new_start_bitrate)) { + send_params.codec.startBitrate = new_start_bitrate; + } - if (!SetSendCodec(new_codec)) { - return false; + if (!SetSendParams(send_channel, send_params)) { + return false; + } + LogSendCodecChange("SetOptions()"); } - LogSendCodecChange("SetOptions()"); } + int buffer_latency; if (Changed(options.buffered_mode_latency, original.buffered_mode_latency, @@ -3676,26 +3684,9 @@ bool WebRtcVideoMediaChannel::SetSendCodec( VideoFormatFromVieCodec(codec), WebRtcVideoChannelSendInfo::kAdaptFormatTypeCodec); - MaybeRegisterExternalEncoder(send_channel, codec); - VideoSendParams send_params = send_channel->send_params(); send_params.codec = codec; - if (!SetSendParams(send_channel, send_params)) { - return false; - } - - // NOTE: SetRtxSendPayloadType must be called after all simulcast SSRCs - // are configured. Otherwise ssrc's configured after this point will use - // the primary PT for RTX. - const int channel_id = send_channel->channel_id(); - if (send_rtx_type_ != -1 && - engine()->vie()->rtp()->SetRtxSendPayloadType(channel_id, - send_rtx_type_) != 0) { - LOG_RTCERR2(SetRtxSendPayloadType, channel_id, send_rtx_type_); - return false; - } - - return true; + return SetSendParams(send_channel, send_params); } static std::string ToString(webrtc::VideoCodecComplexity complexity) { @@ -3872,6 +3863,8 @@ bool WebRtcVideoMediaChannel::SetSendParams( const VideoSendParams& send_params) { const int channel_id = send_channel->channel_id(); + MaybeRegisterExternalEncoder(send_channel, send_params.codec); + CapturedFrameInfo frame; send_channel->last_captured_frame_info().Get(&frame); @@ -3923,10 +3916,18 @@ bool WebRtcVideoMediaChannel::SetSendParams( } engine()->vie()->rtp()->SetTransmissionSmoothingStatus(channel_id, true); - if (send_channel->IsActive()) { - if (!SetSendSsrcs(channel_id, send_params.stream, codec)) { - return false; - } + if (!SetSendSsrcs(channel_id, send_params.stream, codec)) { + return false; + } + + // NOTE: SetRtxSendPayloadType must be called after all SSRCs are + // configured. Otherwise ssrc's configured after this point will use + // the primary PT for RTX. + if (send_rtx_type_ != -1 && + engine()->vie()->rtp()->SetRtxSendPayloadType(channel_id, + send_rtx_type_) != 0) { + LOG_RTCERR2(SetRtxSendPayloadType, channel_id, send_rtx_type_); + return false; } send_channel->set_send_params(send_params); -- cgit v1.2.3 From 31e29d7cd5e7c348d2b39546796a510b6433ae2a Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Wed, 5 Nov 2014 13:25:48 +0000 Subject: (Auto)update libjingle 79205306-> 79244016 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7633 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine.cc | 10 ++++++---- media/webrtc/webrtcvideoengine.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc index d0ed46d..a0a8d81 100644 --- a/media/webrtc/webrtcvideoengine.cc +++ b/media/webrtc/webrtcvideoengine.cc @@ -1661,10 +1661,12 @@ bool WebRtcVideoMediaChannel::Init() { } WebRtcVideoMediaChannel::~WebRtcVideoMediaChannel() { - const bool send = false; - SetSend(send); - const bool render = false; - SetRender(render); + Terminate(); +} + +void WebRtcVideoMediaChannel::Terminate() { + SetSend(false); + SetRender(false); while (!send_channels_.empty()) { if (!DeleteSendChannel(send_channels_.begin()->first)) { diff --git a/media/webrtc/webrtcvideoengine.h b/media/webrtc/webrtcvideoengine.h index 2966511..eee82c8 100644 --- a/media/webrtc/webrtcvideoengine.h +++ b/media/webrtc/webrtcvideoengine.h @@ -330,6 +330,7 @@ class WebRtcVideoMediaChannel : public rtc::MessageHandler, virtual void OnMessage(rtc::Message* msg) OVERRIDE; protected: + void Terminate(); int GetLastEngineError() { return engine()->GetLastEngineError(); } // webrtc::Transport: -- cgit v1.2.3 From 16cad083760474d71bdc3e990fd2f85c0245f000 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Wed, 5 Nov 2014 14:05:29 +0000 Subject: Wire up bandwidth stats to the new API and webrtcvideoengine2. Adds stats to verify bandwidth and pacer stats. BUG=1788 R=mflodman@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/24969004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7634 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine2.cc | 39 ++++++++++++++++++++++++++--- media/webrtc/webrtcvideoengine2.h | 1 + media/webrtc/webrtcvideoengine2_unittest.cc | 9 +++---- media/webrtc/webrtcvideoengine2_unittest.h | 3 +-- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index d79f71d..5062fb9 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -1202,7 +1202,21 @@ void WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { void WebRtcVideoChannel2::FillBandwidthEstimationStats( VideoMediaInfo* video_media_info) { - // TODO(pbos): Implement. + BandwidthEstimationInfo bwe_info; + webrtc::Call::Stats stats = call_->GetStats(); + bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; + bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; + bwe_info.bucket_delay = stats.pacer_delay_ms; + + // Get send stream bitrate stats. + rtc::CritScope stream_lock(&stream_crit_); + for (std::map::iterator stream = + send_streams_.begin(); + stream != send_streams_.end(); + ++stream) { + stream->second->FillBandwidthEstimationInfo(&bwe_info); + } + video_media_info->bw_estimations.push_back(bwe_info); } bool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { @@ -1842,12 +1856,12 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { info.framerate_input = stats.input_frame_rate; info.framerate_sent = stats.encode_frame_rate; - for (std::map::iterator it = + for (std::map::iterator it = stats.substreams.begin(); it != stats.substreams.end(); ++it) { // TODO(pbos): Wire up additional stats, such as padding bytes. - webrtc::StreamStats stream_stats = it->second; + webrtc::SsrcStats stream_stats = it->second; info.bytes_sent += stream_stats.rtp_stats.bytes + stream_stats.rtp_stats.header_bytes + stream_stats.rtp_stats.padding_bytes; @@ -1857,7 +1871,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { if (!stats.substreams.empty()) { // TODO(pbos): Report fraction lost per SSRC. - webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; + webrtc::SsrcStats first_stream_stats = stats.substreams.begin()->second; info.fraction_lost = static_cast(first_stream_stats.rtcp_stats.fraction_lost) / (1 << 8); @@ -1884,6 +1898,23 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { return info; } +void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( + BandwidthEstimationInfo* bwe_info) { + rtc::CritScope cs(&lock_); + if (stream_ == NULL) { + return; + } + webrtc::VideoSendStream::Stats stats = stream_->GetStats(); + for (std::map::iterator it = + stats.substreams.begin(); + it != stats.substreams.end(); + ++it) { + bwe_info->transmit_bitrate += it->second.total_bitrate_bps; + bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; + } + bwe_info->actual_enc_bitrate = stats.media_bitrate_bps; +} + void WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest( CoordinatedVideoAdapter::AdaptRequest adapt_request) { rtc::CritScope cs(&lock_); diff --git a/media/webrtc/webrtcvideoengine2.h b/media/webrtc/webrtcvideoengine2.h index 0b812ef..299ac35 100644 --- a/media/webrtc/webrtcvideoengine2.h +++ b/media/webrtc/webrtcvideoengine2.h @@ -315,6 +315,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, void Stop(); VideoSenderInfo GetVideoSenderInfo(); + void FillBandwidthEstimationInfo(BandwidthEstimationInfo* bwe_info); void OnCpuResolutionRequest( CoordinatedVideoAdapter::AdaptRequest adapt_request); diff --git a/media/webrtc/webrtcvideoengine2_unittest.cc b/media/webrtc/webrtcvideoengine2_unittest.cc index 0b85723..afea370 100644 --- a/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/media/webrtc/webrtcvideoengine2_unittest.cc @@ -294,12 +294,9 @@ webrtc::PacketReceiver* FakeCall::Receiver() { return NULL; } -uint32_t FakeCall::SendBitrateEstimate() { - return 0; -} - -uint32_t FakeCall::ReceiveBitrateEstimate() { - return 0; +webrtc::Call::Stats FakeCall::GetStats() const { + webrtc::Call::Stats stats; + return stats; } void FakeCall::SignalNetworkState(webrtc::Call::NetworkState state) { diff --git a/media/webrtc/webrtcvideoengine2_unittest.h b/media/webrtc/webrtcvideoengine2_unittest.h index 3b62289..48c4f64 100644 --- a/media/webrtc/webrtcvideoengine2_unittest.h +++ b/media/webrtc/webrtcvideoengine2_unittest.h @@ -127,8 +127,7 @@ class FakeCall : public webrtc::Call { webrtc::VideoReceiveStream* receive_stream) OVERRIDE; virtual webrtc::PacketReceiver* Receiver() OVERRIDE; - virtual uint32_t SendBitrateEstimate() OVERRIDE; - virtual uint32_t ReceiveBitrateEstimate() OVERRIDE; + virtual webrtc::Call::Stats GetStats() const OVERRIDE; virtual void SignalNetworkState(webrtc::Call::NetworkState state) OVERRIDE; -- cgit v1.2.3 From 7d974c11e23898cd59838c79751b96c45b09ec4b Mon Sep 17 00:00:00 2001 From: "tkchin@webrtc.org" Date: Wed, 5 Nov 2014 22:01:53 +0000 Subject: This fixes a small memory leak (found using Xcode/Instruments on iOS) in the ObjC bindings of PeerConnection. The generated session description has to be released by the recipient BUG=3985 R=tkchin@webrtc.org Review URL: https://webrtc-codereview.appspot.com/28959004 Patch from Matthias Liebig . git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7636 4adac7df-926f-26a2-2b94-8c16560cd09d --- app/webrtc/objc/RTCPeerConnection.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/app/webrtc/objc/RTCPeerConnection.mm b/app/webrtc/objc/RTCPeerConnection.mm index 925de73..7767f76 100644 --- a/app/webrtc/objc/RTCPeerConnection.mm +++ b/app/webrtc/objc/RTCPeerConnection.mm @@ -68,6 +68,7 @@ class RTCCreateSessionDescriptionObserver [_delegate peerConnection:_peerConnection didCreateSessionDescription:session error:nil]; + delete desc; } virtual void OnFailure(const std::string& error) OVERRIDE { -- cgit v1.2.3 From 05e3f539cc794fe04d2e9b2d85c437f7e069ba6c Mon Sep 17 00:00:00 2001 From: "henrik.lundin@webrtc.org" Date: Thu, 6 Nov 2014 08:55:01 +0000 Subject: Advertise G722 as 8 kHz rather than 16 kHz G722 is a 16 kHz (wideband) speech codec, but a "bug" in the RFC has it listed as 8 kHz. This means that the codec should be advertised as 8 kHz in SDP messages. This change fixes that. R=juberti@google.com TBR=pthatcher@webrtc.org BUG=3951 TEST=Verify that the G722 is advertised as a=rtpmap:9 G722/8000, not /16000. Review URL: https://webrtc-codereview.appspot.com/27879004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7645 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvoiceengine.cc | 29 +++++++++++++++++++++++++++-- media/webrtc/webrtcvoiceengine.h | 1 + media/webrtc/webrtcvoiceengine_unittest.cc | 26 +++++++++++++++++++++----- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/media/webrtc/webrtcvoiceengine.cc b/media/webrtc/webrtcvoiceengine.cc index 95e16e4..6394f09 100644 --- a/media/webrtc/webrtcvoiceengine.cc +++ b/media/webrtc/webrtcvoiceengine.cc @@ -110,6 +110,7 @@ static const int kDefaultAudioDeviceId = 0; static const char kIsacCodecName[] = "ISAC"; static const char kL16CodecName[] = "L16"; +static const char kG722CodecName[] = "G722"; // Parameter used for NACK. // This value is equivalent to 5 seconds of audio data at 20 ms per packet. @@ -485,12 +486,24 @@ static void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); } +// Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC +// which says that G722 should be advertised as 8 kHz although it is a 16 kHz +// codec. +static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { + if (_stricmp(voe_codec->plname, kG722CodecName) == 0) { + // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine + // has changed, and this special case is no longer needed. + ASSERT(voe_codec->plfreq != new_plfreq); + voe_codec->plfreq = new_plfreq; + } +} + void WebRtcVoiceEngine::ConstructCodecs() { LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { + if (GetVoeCodec(i, voe_codec)) { // Skip uncompressed formats. if (_stricmp(voe_codec.plname, kL16CodecName) == 0) { continue; @@ -540,6 +553,15 @@ void WebRtcVoiceEngine::ConstructCodecs() { std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); } +bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst& codec) { + if (voe_wrapper_->codec()->GetCodec(index, codec) != -1) { + // Change the sample rate of G722 to 8000 to match SDP. + MaybeFixupG722(&codec, 8000); + return true; + } + return false; +} + WebRtcVoiceEngine::~WebRtcVoiceEngine() { LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { @@ -1224,7 +1246,7 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { + if (GetVoeCodec(i, voe_codec)) { AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, voe_codec.rate, voe_codec.channels, 0); bool multi_rate = IsCodecMultiRate(voe_codec); @@ -1243,6 +1265,9 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, voe_codec.rate = in.bitrate; } + // Reset G722 sample rate to 16000 to match WebRTC. + MaybeFixupG722(&voe_codec, 16000); + // Apply codec-specific settings. if (IsIsac(codec)) { // If ISAC and an explicit bitrate is not specified, diff --git a/media/webrtc/webrtcvoiceengine.h b/media/webrtc/webrtcvoiceengine.h index f19059b..34b9f3c 100644 --- a/media/webrtc/webrtcvoiceengine.h +++ b/media/webrtc/webrtcvoiceengine.h @@ -199,6 +199,7 @@ class WebRtcVoiceEngine void Construct(); void ConstructCodecs(); + bool GetVoeCodec(int index, webrtc::CodecInst& codec); bool InitInternal(); bool EnsureSoundclipEngineInit(); void SetTraceFilter(int filter); diff --git a/media/webrtc/webrtcvoiceengine_unittest.cc b/media/webrtc/webrtcvoiceengine_unittest.cc index 5deabd2..5eb6e24 100644 --- a/media/webrtc/webrtcvoiceengine_unittest.cc +++ b/media/webrtc/webrtcvoiceengine_unittest.cc @@ -52,14 +52,16 @@ static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0); static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0); static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0); static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0); +static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0); +static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0); static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0); static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0); static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0); static const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0); static const cricket::AudioCodec* const kAudioCodecs[] = { - &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec, - &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, + &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kG722CodecVoE, + &kRedCodec, &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, }; const char kRingbackTone[] = "RIFF____WAVE____ABCD1234"; static uint32 kSsrc1 = 0x99; @@ -770,6 +772,20 @@ TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) { EXPECT_EQ(1, voe_.GetNumSetSendCodecs()); } +// Verify that G722 is set with 16000 samples per second to WebRTC. +TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) { + EXPECT_TRUE(SetupEngine()); + int channel_num = voe_.GetLastChannel(); + std::vector codecs; + codecs.push_back(kG722CodecSdp); + EXPECT_TRUE(channel_->SetSendCodecs(codecs)); + webrtc::CodecInst gcodec; + EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); + EXPECT_STREQ("G722", gcodec.plname); + EXPECT_EQ(1, gcodec.channels); + EXPECT_EQ(16000, gcodec.plfreq); +} + // Test that if clockrate is not 48000 for opus, we fail. TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) { EXPECT_TRUE(SetupEngine()); @@ -3208,7 +3224,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(96, "G722", 16000, 0, 1, 0))); + cricket::AudioCodec(96, "G722", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "red", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( @@ -3225,7 +3241,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722 + cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722 EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN // Check sample/bitrate matching. @@ -3248,7 +3264,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_EQ(103, it->id); } else if (it->name == "ISAC" && it->clockrate == 32000) { EXPECT_EQ(104, it->id); - } else if (it->name == "G722" && it->clockrate == 16000) { + } else if (it->name == "G722" && it->clockrate == 8000) { EXPECT_EQ(9, it->id); } else if (it->name == "telephone-event") { EXPECT_EQ(126, it->id); -- cgit v1.2.3 From 44fec8313eaf730670d3d582d3698a7e8b0efb7a Mon Sep 17 00:00:00 2001 From: "mcasas@webrtc.org" Date: Thu, 6 Nov 2014 09:05:48 +0000 Subject: AppRTCDemoActivity: Add a config CheckBox for enabling/disabling CPU overuse adaptation. Also removed some unused "summary" ListPreference fields. The looks of it can be found in [1] (lowest row). [1] https://drive.google.com/file/d/0By6DR2QIwc_ZQm9TMW5YVEpsMWc/view?usp=sharing R=glaznev@webrtc.org Review URL: https://webrtc-codereview.appspot.com/27939004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7646 4adac7df-926f-26a2-2b94-8c16560cd09d --- examples/android/res/values/arrays.xml | 2 +- examples/android/res/values/strings.xml | 10 +++++++--- examples/android/res/xml/preferences.xml | 11 +++++++---- examples/android/src/org/appspot/apprtc/ConnectActivity.java | 10 ++++++++++ .../android/src/org/appspot/apprtc/SettingsActivity.java | 12 ++++++++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/examples/android/res/values/arrays.xml b/examples/android/res/values/arrays.xml index 3127a85..30159ba 100644 --- a/examples/android/res/values/arrays.xml +++ b/examples/android/res/values/arrays.xml @@ -6,6 +6,7 @@ VGA (640 x 480) QVGA (320 x 240) + Default 1280 x 720 @@ -18,5 +19,4 @@ 30 fps 15 fps - diff --git a/examples/android/res/values/strings.xml b/examples/android/res/values/strings.xml index 2a1d64a..774eee1 100644 --- a/examples/android/res/values/strings.xml +++ b/examples/android/res/values/strings.xml @@ -29,19 +29,23 @@ url_preference Connection URL: - AppRTC connection server URL. Enter AppRTC connection server URL. https://apprtc.appspot.com resolution_preference Video resolution. - Video resolution. Enter AppRTC local video resolution. Default fps_preference Camera fps. - Camera fps. Enter local camera fps. Default + + cpu_usage_detection + CPU overuse detection. + Adapt transmission to CPU status. + true + Enabled + Disabled diff --git a/examples/android/res/xml/preferences.xml b/examples/android/res/xml/preferences.xml index f3f91d8..b8c08bb 100644 --- a/examples/android/res/xml/preferences.xml +++ b/examples/android/res/xml/preferences.xml @@ -3,14 +3,12 @@ - \ No newline at end of file + + + diff --git a/examples/android/src/org/appspot/apprtc/ConnectActivity.java b/examples/android/src/org/appspot/apprtc/ConnectActivity.java index 8f00c1c..ce99bbf 100644 --- a/examples/android/src/org/appspot/apprtc/ConnectActivity.java +++ b/examples/android/src/org/appspot/apprtc/ConnectActivity.java @@ -73,6 +73,7 @@ public class ConnectActivity extends Activity { private String keyprefUrl; private String keyprefResolution; private String keyprefFps; + private String keyprefCpuUsageDetection; private String keyprefRoom; private String keyprefRoomList; private ArrayList roomList; @@ -88,6 +89,7 @@ public class ConnectActivity extends Activity { keyprefUrl = getString(R.string.pref_url_key); keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); + keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); keyprefRoom = getString(R.string.pref_room_key); keyprefRoomList = getString(R.string.pref_room_list_key); @@ -252,6 +254,14 @@ public class ConnectActivity extends Activity { url += "&hd=true"; } } + // Test if CpuOveruseDetection should be disabled. By default is on. + boolean cpuOveruseDetection = sharedPref.getBoolean( + keyprefCpuUsageDetection, + Boolean.valueOf( + getString(R.string.pref_cpu_usage_detection_default))); + if (!cpuOveruseDetection) { + url += "&googCpuOveruseDetection=false"; + } // TODO(kjellander): Add support for custom parameters to the URL. connectToRoom(url); } diff --git a/examples/android/src/org/appspot/apprtc/SettingsActivity.java b/examples/android/src/org/appspot/apprtc/SettingsActivity.java index 2354ceb..eccb67e 100644 --- a/examples/android/src/org/appspot/apprtc/SettingsActivity.java +++ b/examples/android/src/org/appspot/apprtc/SettingsActivity.java @@ -39,6 +39,7 @@ public class SettingsActivity extends Activity private String keyprefUrl; private String keyprefResolution; private String keyprefFps; + private String keyprefCpuUsageDetection; @Override protected void onCreate(Bundle savedInstanceState) { @@ -46,6 +47,7 @@ public class SettingsActivity extends Activity keyprefUrl = getString(R.string.pref_url_key); keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); + keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); // Display the fragment as the main content. settingsFragment = new SettingsFragment(); @@ -64,6 +66,7 @@ public class SettingsActivity extends Activity updateSummary(sharedPreferences, keyprefUrl); updateSummary(sharedPreferences, keyprefResolution); updateSummary(sharedPreferences, keyprefFps); + updateSummaryB(sharedPreferences, keyprefCpuUsageDetection); } @Override @@ -80,6 +83,8 @@ public class SettingsActivity extends Activity if (key.equals(keyprefUrl) || key.equals(keyprefResolution) || key.equals(keyprefFps)) { updateSummary(sharedPreferences, key); + } else if (key.equals(keyprefCpuUsageDetection)) { + updateSummaryB(sharedPreferences, key); } } @@ -89,4 +94,11 @@ public class SettingsActivity extends Activity updatedPref.setSummary(sharedPreferences.getString(key, "")); } + private void updateSummaryB(SharedPreferences sharedPreferences, String key) { + Preference updatedPref = settingsFragment.findPreference(key); + updatedPref.setSummary(sharedPreferences.getBoolean(key, true) + ? getString(R.string.pref_cpu_usage_detection_on) + : getString(R.string.pref_cpu_usage_detection_off)); + } + } -- cgit v1.2.3 From b7634029b0c3cf9ce213207c27683160f7ba1ddd Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Thu, 6 Nov 2014 09:22:08 +0000 Subject: (Auto)update libjingle 79285346-> 79320771 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7647 4adac7df-926f-26a2-2b94-8c16560cd09d --- examples/android/res/values/arrays.xml | 2 +- examples/android/res/values/strings.xml | 10 +++------- examples/android/res/xml/preferences.xml | 11 ++++------- examples/android/src/org/appspot/apprtc/ConnectActivity.java | 10 ---------- .../android/src/org/appspot/apprtc/SettingsActivity.java | 12 ------------ 5 files changed, 8 insertions(+), 37 deletions(-) diff --git a/examples/android/res/values/arrays.xml b/examples/android/res/values/arrays.xml index 30159ba..3127a85 100644 --- a/examples/android/res/values/arrays.xml +++ b/examples/android/res/values/arrays.xml @@ -6,7 +6,6 @@ VGA (640 x 480) QVGA (320 x 240) - Default 1280 x 720 @@ -19,4 +18,5 @@ 30 fps 15 fps + diff --git a/examples/android/res/values/strings.xml b/examples/android/res/values/strings.xml index 774eee1..2a1d64a 100644 --- a/examples/android/res/values/strings.xml +++ b/examples/android/res/values/strings.xml @@ -29,23 +29,19 @@ url_preference Connection URL: + AppRTC connection server URL. Enter AppRTC connection server URL. https://apprtc.appspot.com resolution_preference Video resolution. + Video resolution. Enter AppRTC local video resolution. Default fps_preference Camera fps. + Camera fps. Enter local camera fps. Default - - cpu_usage_detection - CPU overuse detection. - Adapt transmission to CPU status. - true - Enabled - Disabled diff --git a/examples/android/res/xml/preferences.xml b/examples/android/res/xml/preferences.xml index b8c08bb..f3f91d8 100644 --- a/examples/android/res/xml/preferences.xml +++ b/examples/android/res/xml/preferences.xml @@ -3,12 +3,14 @@ - - - + \ No newline at end of file diff --git a/examples/android/src/org/appspot/apprtc/ConnectActivity.java b/examples/android/src/org/appspot/apprtc/ConnectActivity.java index ce99bbf..8f00c1c 100644 --- a/examples/android/src/org/appspot/apprtc/ConnectActivity.java +++ b/examples/android/src/org/appspot/apprtc/ConnectActivity.java @@ -73,7 +73,6 @@ public class ConnectActivity extends Activity { private String keyprefUrl; private String keyprefResolution; private String keyprefFps; - private String keyprefCpuUsageDetection; private String keyprefRoom; private String keyprefRoomList; private ArrayList roomList; @@ -89,7 +88,6 @@ public class ConnectActivity extends Activity { keyprefUrl = getString(R.string.pref_url_key); keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); - keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); keyprefRoom = getString(R.string.pref_room_key); keyprefRoomList = getString(R.string.pref_room_list_key); @@ -254,14 +252,6 @@ public class ConnectActivity extends Activity { url += "&hd=true"; } } - // Test if CpuOveruseDetection should be disabled. By default is on. - boolean cpuOveruseDetection = sharedPref.getBoolean( - keyprefCpuUsageDetection, - Boolean.valueOf( - getString(R.string.pref_cpu_usage_detection_default))); - if (!cpuOveruseDetection) { - url += "&googCpuOveruseDetection=false"; - } // TODO(kjellander): Add support for custom parameters to the URL. connectToRoom(url); } diff --git a/examples/android/src/org/appspot/apprtc/SettingsActivity.java b/examples/android/src/org/appspot/apprtc/SettingsActivity.java index eccb67e..2354ceb 100644 --- a/examples/android/src/org/appspot/apprtc/SettingsActivity.java +++ b/examples/android/src/org/appspot/apprtc/SettingsActivity.java @@ -39,7 +39,6 @@ public class SettingsActivity extends Activity private String keyprefUrl; private String keyprefResolution; private String keyprefFps; - private String keyprefCpuUsageDetection; @Override protected void onCreate(Bundle savedInstanceState) { @@ -47,7 +46,6 @@ public class SettingsActivity extends Activity keyprefUrl = getString(R.string.pref_url_key); keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); - keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); // Display the fragment as the main content. settingsFragment = new SettingsFragment(); @@ -66,7 +64,6 @@ public class SettingsActivity extends Activity updateSummary(sharedPreferences, keyprefUrl); updateSummary(sharedPreferences, keyprefResolution); updateSummary(sharedPreferences, keyprefFps); - updateSummaryB(sharedPreferences, keyprefCpuUsageDetection); } @Override @@ -83,8 +80,6 @@ public class SettingsActivity extends Activity if (key.equals(keyprefUrl) || key.equals(keyprefResolution) || key.equals(keyprefFps)) { updateSummary(sharedPreferences, key); - } else if (key.equals(keyprefCpuUsageDetection)) { - updateSummaryB(sharedPreferences, key); } } @@ -94,11 +89,4 @@ public class SettingsActivity extends Activity updatedPref.setSummary(sharedPreferences.getString(key, "")); } - private void updateSummaryB(SharedPreferences sharedPreferences, String key) { - Preference updatedPref = settingsFragment.findPreference(key); - updatedPref.setSummary(sharedPreferences.getBoolean(key, true) - ? getString(R.string.pref_cpu_usage_detection_on) - : getString(R.string.pref_cpu_usage_detection_off)); - } - } -- cgit v1.2.3 From 59ad3d2644d79611c666559828dd9e5319698679 Mon Sep 17 00:00:00 2001 From: "andresp@webrtc.org" Date: Thu, 6 Nov 2014 11:16:32 +0000 Subject: Removing unused method GetDefaultVideoEncoderConfig. R=pbos@webrtc.org, tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/27959004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7649 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/base/fakemediaengine.h | 3 --- media/base/filemediaengine.h | 3 --- media/base/mediaengine.h | 10 ---------- media/webrtc/webrtcmediaengine.h | 3 --- media/webrtc/webrtcvideoengine.cc | 11 ----------- media/webrtc/webrtcvideoengine.h | 1 - media/webrtc/webrtcvideoengine2.cc | 4 ---- media/webrtc/webrtcvideoengine2.h | 1 - 8 files changed, 36 deletions(-) diff --git a/media/base/fakemediaengine.h b/media/base/fakemediaengine.h index db5e2e4..ff6ae16 100644 --- a/media/base/fakemediaengine.h +++ b/media/base/fakemediaengine.h @@ -879,9 +879,6 @@ class FakeVideoEngine : public FakeBaseEngine { default_encoder_config_ = config; return true; } - VideoEncoderConfig GetDefaultEncoderConfig() const { - return default_encoder_config_; - } const VideoEncoderConfig& default_encoder_config() const { return default_encoder_config_; } diff --git a/media/base/filemediaengine.h b/media/base/filemediaengine.h index 9cc066d..ba29ab3 100644 --- a/media/base/filemediaengine.h +++ b/media/base/filemediaengine.h @@ -93,9 +93,6 @@ class FileMediaEngine : public MediaEngineInterface { virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { return true; } - virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const { - return VideoEncoderConfig(); - } virtual bool SetSoundDevices(const Device* in_dev, const Device* out_dev) { return true; } diff --git a/media/base/mediaengine.h b/media/base/mediaengine.h index e7222f2..b8d661c 100644 --- a/media/base/mediaengine.h +++ b/media/base/mediaengine.h @@ -99,10 +99,6 @@ class MediaEngineInterface { // and encode video. virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) = 0; - // Gets the default (maximum) codec/resolution and encoder option used to - // capture and encode video, as set by SetDefaultVideoEncoderConfig or the - // default from the video engine if not previously set. - virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const = 0; // Device selection // TODO(tschmelcher): Add method for selecting the soundclip device. @@ -219,9 +215,6 @@ class CompositeMediaEngine : public MediaEngineInterface { virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { return video_.SetDefaultEncoderConfig(config); } - virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const { - return video_.GetDefaultEncoderConfig(); - } virtual bool SetSoundDevices(const Device* in_device, const Device* out_device) { @@ -347,9 +340,6 @@ class NullVideoEngine { return NULL; } bool SetOptions(const VideoOptions& options) { return true; } - VideoEncoderConfig GetDefaultEncoderConfig() const { - return VideoEncoderConfig(); - } bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { return true; } diff --git a/media/webrtc/webrtcmediaengine.h b/media/webrtc/webrtcmediaengine.h index bfcfb2a..b4436cd 100644 --- a/media/webrtc/webrtcmediaengine.h +++ b/media/webrtc/webrtcmediaengine.h @@ -130,9 +130,6 @@ class DelegatingWebRtcMediaEngine : public cricket::MediaEngineInterface { const VideoEncoderConfig& config) OVERRIDE { return delegate_->SetDefaultVideoEncoderConfig(config); } - virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const OVERRIDE { - return delegate_->GetDefaultVideoEncoderConfig(); - } virtual bool SetSoundDevices( const Device* in_device, const Device* out_device) OVERRIDE { return delegate_->SetSoundDevices(in_device, out_device); diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc index a0a8d81..6dacadd 100644 --- a/media/webrtc/webrtcvideoengine.cc +++ b/media/webrtc/webrtcvideoengine.cc @@ -1144,17 +1144,6 @@ bool WebRtcVideoEngine::SetDefaultEncoderConfig( return SetDefaultCodec(config.max_codec); } -VideoEncoderConfig WebRtcVideoEngine::GetDefaultEncoderConfig() const { - ASSERT(!video_codecs_.empty()); - VideoCodec max_codec(kVideoCodecPrefs[0].payload_type, - kVideoCodecPrefs[0].name, - video_codecs_[0].width, - video_codecs_[0].height, - video_codecs_[0].framerate, - 0); - return VideoEncoderConfig(max_codec); -} - // SetDefaultCodec may be called while the capturer is running. For example, a // test call is started in a page with QVGA default codec, and then a real call // is started in another page with VGA default codec. This is the corner case diff --git a/media/webrtc/webrtcvideoengine.h b/media/webrtc/webrtcvideoengine.h index eee82c8..d577b4b 100644 --- a/media/webrtc/webrtcvideoengine.h +++ b/media/webrtc/webrtcvideoengine.h @@ -108,7 +108,6 @@ class WebRtcVideoEngine : public sigslot::has_slots<>, int GetCapabilities(); bool SetDefaultEncoderConfig(const VideoEncoderConfig& config); - VideoEncoderConfig GetDefaultEncoderConfig() const; // TODO(pbos): Remove when all call sites use VideoOptions. virtual WebRtcVideoMediaChannel* CreateChannel( diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index 5062fb9..a641a58 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -427,10 +427,6 @@ bool WebRtcVideoEngine2::SetDefaultEncoderConfig( return true; } -VideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { - return VideoEncoderConfig(DefaultVideoCodec()); -} - WebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( const VideoOptions& options, VoiceMediaChannel* voice_channel) { diff --git a/media/webrtc/webrtcvideoengine2.h b/media/webrtc/webrtcvideoengine2.h index 299ac35..68cacc0 100644 --- a/media/webrtc/webrtcvideoengine2.h +++ b/media/webrtc/webrtcvideoengine2.h @@ -145,7 +145,6 @@ class WebRtcVideoEngine2 : public sigslot::has_slots<> { int GetCapabilities(); bool SetDefaultEncoderConfig(const VideoEncoderConfig& config); - VideoEncoderConfig GetDefaultEncoderConfig() const; WebRtcVideoChannel2* CreateChannel(const VideoOptions& options, VoiceMediaChannel* voice_channel); -- cgit v1.2.3 From 99766a1e81973265d444f71c492960819c12e6e2 Mon Sep 17 00:00:00 2001 From: "perkj@webrtc.org" Date: Thu, 6 Nov 2014 12:16:36 +0000 Subject: Remove deprecated PeerConnection APIs. Removes PeerConnectionObserver::OnError. Removes MediaConstraints argument to PeerConnection::AddStream. None of these have ever been implemented and have been removed from the spec. R=tommi@chromium.org Review URL: https://webrtc-codereview.appspot.com/24189004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7650 4adac7df-926f-26a2-2b94-8c16560cd09d --- app/webrtc/peerconnection.cc | 5 ----- app/webrtc/peerconnection.h | 2 -- app/webrtc/peerconnectioninterface.h | 14 +------------- app/webrtc/peerconnectionproxy.h | 2 -- 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/app/webrtc/peerconnection.cc b/app/webrtc/peerconnection.cc index b64caf7..64ddcad 100644 --- a/app/webrtc/peerconnection.cc +++ b/app/webrtc/peerconnection.cc @@ -420,11 +420,6 @@ bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { return true; } -bool PeerConnection::AddStream(MediaStreamInterface* local_stream, - const MediaConstraintsInterface* constraints) { - return AddStream(local_stream); -} - void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { mediastream_signaling_->RemoveLocalStream(local_stream); if (IsClosed()) { diff --git a/app/webrtc/peerconnection.h b/app/webrtc/peerconnection.h index 355211c..68aa154 100644 --- a/app/webrtc/peerconnection.h +++ b/app/webrtc/peerconnection.h @@ -66,8 +66,6 @@ class PeerConnection : public PeerConnectionInterface, virtual rtc::scoped_refptr local_streams(); virtual rtc::scoped_refptr remote_streams(); virtual bool AddStream(MediaStreamInterface* local_stream); - virtual bool AddStream(MediaStreamInterface* local_stream, - const MediaConstraintsInterface* constraints); virtual void RemoveStream(MediaStreamInterface* local_stream); virtual rtc::scoped_refptr CreateDtmfSender( diff --git a/app/webrtc/peerconnectioninterface.h b/app/webrtc/peerconnectioninterface.h index 68b7879..73a4812 100644 --- a/app/webrtc/peerconnectioninterface.h +++ b/app/webrtc/peerconnectioninterface.h @@ -255,15 +255,7 @@ class PeerConnectionInterface : public rtc::RefCountInterface { // Add a new MediaStream to be sent on this PeerConnection. // Note that a SessionDescription negotiation is needed before the // remote peer can receive the stream. - // TODO(perkj): Make pure virtual once Chrome mocks have implemented. - virtual bool AddStream(MediaStreamInterface* stream) { return false;} - - // Deprecated: - // TODO(perkj): Remove once its not used by Chrome. - virtual bool AddStream(MediaStreamInterface* stream, - const MediaConstraintsInterface* constraints) { - return false; - } + virtual bool AddStream(MediaStreamInterface* stream) = 0; // Remove a MediaStream from this PeerConnection. // Note that a SessionDescription negotiation is need before the @@ -351,10 +343,6 @@ class PeerConnectionObserver { kIceState, }; - // Deprecated. - // TODO(perkj): Remove once its not used by Chrome. - virtual void OnError() {} - // Triggered when the SignalingState changed. virtual void OnSignalingChange( PeerConnectionInterface::SignalingState new_state) {} diff --git a/app/webrtc/peerconnectionproxy.h b/app/webrtc/peerconnectionproxy.h index 571c676..852d852 100644 --- a/app/webrtc/peerconnectionproxy.h +++ b/app/webrtc/peerconnectionproxy.h @@ -40,8 +40,6 @@ BEGIN_PROXY_MAP(PeerConnection) PROXY_METHOD0(rtc::scoped_refptr, remote_streams) PROXY_METHOD1(bool, AddStream, MediaStreamInterface*) - PROXY_METHOD2(bool, AddStream, MediaStreamInterface*, - const MediaConstraintsInterface*); PROXY_METHOD1(void, RemoveStream, MediaStreamInterface*) PROXY_METHOD1(rtc::scoped_refptr, CreateDtmfSender, AudioTrackInterface*) -- cgit v1.2.3 From d0a8777044d2271f163e56cb4eb199eb55246873 Mon Sep 17 00:00:00 2001 From: "henrika@webrtc.org" Date: Thu, 6 Nov 2014 12:19:19 +0000 Subject: Volume buttons in AppRTCDemo should affect output audio volume. BUG=3279 R=glaznev@webrtc.org Review URL: https://webrtc-codereview.appspot.com/32399004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7651 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../src/org/appspot/apprtc/AppRTCAudioManager.java | 108 +++++++++++++++++++++ .../src/org/appspot/apprtc/AppRTCDemoActivity.java | 24 +++-- libjingle_examples.gyp | 1 + 3 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java diff --git a/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java b/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java new file mode 100644 index 0000000..b2a1a44 --- /dev/null +++ b/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java @@ -0,0 +1,108 @@ +/* + * 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. + */ + +package org.appspot.apprtc; + +import android.content.Context; +import android.media.AudioManager; +import android.util.Log; + +/** + * AppRTCAudioManager manages all audio related parts of the AppRTC demo. + * TODO(henrika): add support for device enumeration, device selection etc. + */ +public class AppRTCAudioManager { + private static final String TAG = "AppRTCAudioManager"; + + private boolean initialized = false; + private AudioManager audioManager; + private int savedAudioMode = AudioManager.MODE_INVALID; + private boolean savedIsSpeakerPhoneOn = false; + private boolean savedIsMicrophoneMute = false; + + /** Construction */ + static AppRTCAudioManager create(Context context) { + return new AppRTCAudioManager(context); + } + + private AppRTCAudioManager(Context context) { + Log.d(TAG, "AppRTCAudioManager"); + audioManager = ((AudioManager) context.getSystemService( + Context.AUDIO_SERVICE)); + } + + public void init() { + Log.d(TAG, "init"); + if (initialized) { + return; + } + + // Store current audio state so we can restore it when close() is called. + savedAudioMode = audioManager.getMode(); + savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); + savedIsMicrophoneMute = audioManager.isMicrophoneMute(); + + // The AppRTC demo shall always run in COMMUNICATION mode since it will + // result in best possible "VoIP settings", like audio routing, volume + // control etc. + audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + + initialized = true; + } + + public void close() { + Log.d(TAG, "close"); + if (!initialized) { + return; + } + + // Restore previously stored audio states. + setSpeakerphoneOn(savedIsSpeakerPhoneOn); + setMicrophoneMute(savedIsMicrophoneMute); + audioManager.setMode(savedAudioMode); + + initialized = false; + } + + /** Sets the speaker phone mode. */ + private void setSpeakerphoneOn(boolean on) { + boolean wasOn = audioManager.isSpeakerphoneOn(); + if (wasOn == on) { + return; + } + audioManager.setSpeakerphoneOn(on); + } + + /** Sets the microphone mute state. */ + private void setMicrophoneMute(boolean on) { + boolean wasMuted = audioManager.isMicrophoneMute(); + if (wasMuted == on) { + return; + } + audioManager.setMicrophoneMute(on); + } +} diff --git a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java index ad0e2d5..3ad26af 100644 --- a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java +++ b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java @@ -34,7 +34,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Color; -import android.media.AudioManager; import android.net.Uri; import android.opengl.GLSurfaceView; import android.os.Bundle; @@ -72,6 +71,7 @@ public class AppRTCDemoActivity extends Activity private PeerConnectionClient pc; private AppRTCClient appRtcClient = new GAERTCClient(this, this); private AppRTCSignalingParameters appRtcParameters; + private AppRTCAudioManager audioManager = null; private View rootView; private View menuBar; private GLSurfaceView videoView; @@ -187,15 +187,9 @@ public class AppRTCDemoActivity extends Activity hudView.setVisibility(View.INVISIBLE); addContentView(hudView, hudLayout); - AudioManager audioManager = - ((AudioManager) getSystemService(AUDIO_SERVICE)); - // TODO(fischman): figure out how to do this Right(tm) and remove the - // suppression. - @SuppressWarnings("deprecation") - boolean isWiredHeadsetOn = audioManager.isWiredHeadsetOn(); - audioManager.setMode(isWiredHeadsetOn ? - AudioManager.MODE_IN_CALL : AudioManager.MODE_IN_COMMUNICATION); - audioManager.setSpeakerphoneOn(!isWiredHeadsetOn); + // Create and audio manager that will take care of audio routing, + // audio modes, audio device enumeration etc. + audioManager = AppRTCAudioManager.create(this); final Intent intent = getIntent(); Uri url = intent.getData(); @@ -253,6 +247,10 @@ public class AppRTCDemoActivity extends Activity @Override protected void onDestroy() { disconnect(); + if (audioManager != null) { + audioManager.close(); + audioManager = null; + } super.onDestroy(); } @@ -360,6 +358,12 @@ public class AppRTCDemoActivity extends Activity // All events are called from UI thread. @Override public void onConnectedToRoom(final AppRTCSignalingParameters params) { + if (audioManager != null) { + // Store existing audio settings and change audio mode to + // MODE_IN_COMMUNICATION for best possible VoIP performance. + logAndToast("Initializing the audio manager..."); + audioManager.init(); + } appRtcParameters = params; abortUnless(PeerConnectionFactory.initializeAndroidGlobals( this, true, true, VideoRendererGui.getEGLContext()), diff --git a/libjingle_examples.gyp b/libjingle_examples.gyp index d0f1747..f7ce53b 100755 --- a/libjingle_examples.gyp +++ b/libjingle_examples.gyp @@ -344,6 +344,7 @@ 'examples/android/res/values/arrays.xml', 'examples/android/res/values/strings.xml', 'examples/android/res/xml/preferences.xml', + 'examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java', 'examples/android/src/org/appspot/apprtc/AppRTCClient.java', 'examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java', 'examples/android/src/org/appspot/apprtc/ConnectActivity.java', -- cgit v1.2.3 From eb0e23196dcb82b90c94202d1ed39e6c8abbe96a Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Thu, 6 Nov 2014 12:44:55 +0000 Subject: (Auto)update libjingle 79326895-> 79329222 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7652 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../src/org/appspot/apprtc/AppRTCAudioManager.java | 108 --------------------- .../src/org/appspot/apprtc/AppRTCDemoActivity.java | 24 ++--- libjingle_examples.gyp | 1 - 3 files changed, 10 insertions(+), 123 deletions(-) delete mode 100644 examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java diff --git a/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java b/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java deleted file mode 100644 index b2a1a44..0000000 --- a/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java +++ /dev/null @@ -1,108 +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. - */ - -package org.appspot.apprtc; - -import android.content.Context; -import android.media.AudioManager; -import android.util.Log; - -/** - * AppRTCAudioManager manages all audio related parts of the AppRTC demo. - * TODO(henrika): add support for device enumeration, device selection etc. - */ -public class AppRTCAudioManager { - private static final String TAG = "AppRTCAudioManager"; - - private boolean initialized = false; - private AudioManager audioManager; - private int savedAudioMode = AudioManager.MODE_INVALID; - private boolean savedIsSpeakerPhoneOn = false; - private boolean savedIsMicrophoneMute = false; - - /** Construction */ - static AppRTCAudioManager create(Context context) { - return new AppRTCAudioManager(context); - } - - private AppRTCAudioManager(Context context) { - Log.d(TAG, "AppRTCAudioManager"); - audioManager = ((AudioManager) context.getSystemService( - Context.AUDIO_SERVICE)); - } - - public void init() { - Log.d(TAG, "init"); - if (initialized) { - return; - } - - // Store current audio state so we can restore it when close() is called. - savedAudioMode = audioManager.getMode(); - savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); - savedIsMicrophoneMute = audioManager.isMicrophoneMute(); - - // The AppRTC demo shall always run in COMMUNICATION mode since it will - // result in best possible "VoIP settings", like audio routing, volume - // control etc. - audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); - - initialized = true; - } - - public void close() { - Log.d(TAG, "close"); - if (!initialized) { - return; - } - - // Restore previously stored audio states. - setSpeakerphoneOn(savedIsSpeakerPhoneOn); - setMicrophoneMute(savedIsMicrophoneMute); - audioManager.setMode(savedAudioMode); - - initialized = false; - } - - /** Sets the speaker phone mode. */ - private void setSpeakerphoneOn(boolean on) { - boolean wasOn = audioManager.isSpeakerphoneOn(); - if (wasOn == on) { - return; - } - audioManager.setSpeakerphoneOn(on); - } - - /** Sets the microphone mute state. */ - private void setMicrophoneMute(boolean on) { - boolean wasMuted = audioManager.isMicrophoneMute(); - if (wasMuted == on) { - return; - } - audioManager.setMicrophoneMute(on); - } -} diff --git a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java index 3ad26af..ad0e2d5 100644 --- a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java +++ b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java @@ -34,6 +34,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Color; +import android.media.AudioManager; import android.net.Uri; import android.opengl.GLSurfaceView; import android.os.Bundle; @@ -71,7 +72,6 @@ public class AppRTCDemoActivity extends Activity private PeerConnectionClient pc; private AppRTCClient appRtcClient = new GAERTCClient(this, this); private AppRTCSignalingParameters appRtcParameters; - private AppRTCAudioManager audioManager = null; private View rootView; private View menuBar; private GLSurfaceView videoView; @@ -187,9 +187,15 @@ public class AppRTCDemoActivity extends Activity hudView.setVisibility(View.INVISIBLE); addContentView(hudView, hudLayout); - // Create and audio manager that will take care of audio routing, - // audio modes, audio device enumeration etc. - audioManager = AppRTCAudioManager.create(this); + AudioManager audioManager = + ((AudioManager) getSystemService(AUDIO_SERVICE)); + // TODO(fischman): figure out how to do this Right(tm) and remove the + // suppression. + @SuppressWarnings("deprecation") + boolean isWiredHeadsetOn = audioManager.isWiredHeadsetOn(); + audioManager.setMode(isWiredHeadsetOn ? + AudioManager.MODE_IN_CALL : AudioManager.MODE_IN_COMMUNICATION); + audioManager.setSpeakerphoneOn(!isWiredHeadsetOn); final Intent intent = getIntent(); Uri url = intent.getData(); @@ -247,10 +253,6 @@ public class AppRTCDemoActivity extends Activity @Override protected void onDestroy() { disconnect(); - if (audioManager != null) { - audioManager.close(); - audioManager = null; - } super.onDestroy(); } @@ -358,12 +360,6 @@ public class AppRTCDemoActivity extends Activity // All events are called from UI thread. @Override public void onConnectedToRoom(final AppRTCSignalingParameters params) { - if (audioManager != null) { - // Store existing audio settings and change audio mode to - // MODE_IN_COMMUNICATION for best possible VoIP performance. - logAndToast("Initializing the audio manager..."); - audioManager.init(); - } appRtcParameters = params; abortUnless(PeerConnectionFactory.initializeAndroidGlobals( this, true, true, VideoRendererGui.getEGLContext()), diff --git a/libjingle_examples.gyp b/libjingle_examples.gyp index f7ce53b..d0f1747 100755 --- a/libjingle_examples.gyp +++ b/libjingle_examples.gyp @@ -344,7 +344,6 @@ 'examples/android/res/values/arrays.xml', 'examples/android/res/values/strings.xml', 'examples/android/res/xml/preferences.xml', - 'examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java', 'examples/android/src/org/appspot/apprtc/AppRTCClient.java', 'examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java', 'examples/android/src/org/appspot/apprtc/ConnectActivity.java', -- cgit v1.2.3 From f1e9d8b8a9438b6f645d2dca01cb290d53cb5f06 Mon Sep 17 00:00:00 2001 From: "henrik.lundin@webrtc.org" Date: Thu, 6 Nov 2014 15:27:43 +0000 Subject: Revert "Advertise G722 as 8 kHz rather than 16 kHz" This reverts r7645. TBR=pthatcher@webrtc.org BUG=3951 Review URL: https://webrtc-codereview.appspot.com/24199004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7653 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvoiceengine.cc | 29 ++--------------------------- media/webrtc/webrtcvoiceengine.h | 1 - media/webrtc/webrtcvoiceengine_unittest.cc | 26 +++++--------------------- 3 files changed, 7 insertions(+), 49 deletions(-) diff --git a/media/webrtc/webrtcvoiceengine.cc b/media/webrtc/webrtcvoiceengine.cc index 6394f09..95e16e4 100644 --- a/media/webrtc/webrtcvoiceengine.cc +++ b/media/webrtc/webrtcvoiceengine.cc @@ -110,7 +110,6 @@ static const int kDefaultAudioDeviceId = 0; static const char kIsacCodecName[] = "ISAC"; static const char kL16CodecName[] = "L16"; -static const char kG722CodecName[] = "G722"; // Parameter used for NACK. // This value is equivalent to 5 seconds of audio data at 20 ms per packet. @@ -486,24 +485,12 @@ static void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); } -// Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC -// which says that G722 should be advertised as 8 kHz although it is a 16 kHz -// codec. -static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { - if (_stricmp(voe_codec->plname, kG722CodecName) == 0) { - // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine - // has changed, and this special case is no longer needed. - ASSERT(voe_codec->plfreq != new_plfreq); - voe_codec->plfreq = new_plfreq; - } -} - void WebRtcVoiceEngine::ConstructCodecs() { LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (GetVoeCodec(i, voe_codec)) { + if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { // Skip uncompressed formats. if (_stricmp(voe_codec.plname, kL16CodecName) == 0) { continue; @@ -553,15 +540,6 @@ void WebRtcVoiceEngine::ConstructCodecs() { std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); } -bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst& codec) { - if (voe_wrapper_->codec()->GetCodec(index, codec) != -1) { - // Change the sample rate of G722 to 8000 to match SDP. - MaybeFixupG722(&codec, 8000); - return true; - } - return false; -} - WebRtcVoiceEngine::~WebRtcVoiceEngine() { LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { @@ -1246,7 +1224,7 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (GetVoeCodec(i, voe_codec)) { + if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, voe_codec.rate, voe_codec.channels, 0); bool multi_rate = IsCodecMultiRate(voe_codec); @@ -1265,9 +1243,6 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, voe_codec.rate = in.bitrate; } - // Reset G722 sample rate to 16000 to match WebRTC. - MaybeFixupG722(&voe_codec, 16000); - // Apply codec-specific settings. if (IsIsac(codec)) { // If ISAC and an explicit bitrate is not specified, diff --git a/media/webrtc/webrtcvoiceengine.h b/media/webrtc/webrtcvoiceengine.h index 34b9f3c..f19059b 100644 --- a/media/webrtc/webrtcvoiceengine.h +++ b/media/webrtc/webrtcvoiceengine.h @@ -199,7 +199,6 @@ class WebRtcVoiceEngine void Construct(); void ConstructCodecs(); - bool GetVoeCodec(int index, webrtc::CodecInst& codec); bool InitInternal(); bool EnsureSoundclipEngineInit(); void SetTraceFilter(int filter); diff --git a/media/webrtc/webrtcvoiceengine_unittest.cc b/media/webrtc/webrtcvoiceengine_unittest.cc index 5eb6e24..5deabd2 100644 --- a/media/webrtc/webrtcvoiceengine_unittest.cc +++ b/media/webrtc/webrtcvoiceengine_unittest.cc @@ -52,16 +52,14 @@ static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0); static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0); static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0); static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0); -static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0); -static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0); static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0); static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0); static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0); static const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0); static const cricket::AudioCodec* const kAudioCodecs[] = { - &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kG722CodecVoE, - &kRedCodec, &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, + &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec, + &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, }; const char kRingbackTone[] = "RIFF____WAVE____ABCD1234"; static uint32 kSsrc1 = 0x99; @@ -772,20 +770,6 @@ TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) { EXPECT_EQ(1, voe_.GetNumSetSendCodecs()); } -// Verify that G722 is set with 16000 samples per second to WebRTC. -TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) { - EXPECT_TRUE(SetupEngine()); - int channel_num = voe_.GetLastChannel(); - std::vector codecs; - codecs.push_back(kG722CodecSdp); - EXPECT_TRUE(channel_->SetSendCodecs(codecs)); - webrtc::CodecInst gcodec; - EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); - EXPECT_STREQ("G722", gcodec.plname); - EXPECT_EQ(1, gcodec.channels); - EXPECT_EQ(16000, gcodec.plfreq); -} - // Test that if clockrate is not 48000 for opus, we fail. TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) { EXPECT_TRUE(SetupEngine()); @@ -3224,7 +3208,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(96, "G722", 8000, 0, 1, 0))); + cricket::AudioCodec(96, "G722", 16000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "red", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( @@ -3241,7 +3225,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722 + cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722 EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN // Check sample/bitrate matching. @@ -3264,7 +3248,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_EQ(103, it->id); } else if (it->name == "ISAC" && it->clockrate == 32000) { EXPECT_EQ(104, it->id); - } else if (it->name == "G722" && it->clockrate == 8000) { + } else if (it->name == "G722" && it->clockrate == 16000) { EXPECT_EQ(9, it->id); } else if (it->name == "telephone-event") { EXPECT_EQ(126, it->id); -- cgit v1.2.3 From b87c47f71fc54cd45d4660b5d65f06231246d21d Mon Sep 17 00:00:00 2001 From: "henrika@webrtc.org" Date: Thu, 6 Nov 2014 20:35:13 +0000 Subject: Reland Volume buttons in AppRTCDemo should affect output audio volume (part I). Second attempt to land https://webrtc-codereview.appspot.com/32399004/ TBR=perkj@webrtc.org BUG= Review URL: https://webrtc-codereview.appspot.com/30919004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7657 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../src/org/appspot/apprtc/AppRTCAudioManager.java | 108 +++++++++++++++++++++ .../src/org/appspot/apprtc/AppRTCDemoActivity.java | 24 +++-- libjingle_examples.gyp | 1 + 3 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java diff --git a/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java b/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java new file mode 100644 index 0000000..b2a1a44 --- /dev/null +++ b/examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java @@ -0,0 +1,108 @@ +/* + * 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. + */ + +package org.appspot.apprtc; + +import android.content.Context; +import android.media.AudioManager; +import android.util.Log; + +/** + * AppRTCAudioManager manages all audio related parts of the AppRTC demo. + * TODO(henrika): add support for device enumeration, device selection etc. + */ +public class AppRTCAudioManager { + private static final String TAG = "AppRTCAudioManager"; + + private boolean initialized = false; + private AudioManager audioManager; + private int savedAudioMode = AudioManager.MODE_INVALID; + private boolean savedIsSpeakerPhoneOn = false; + private boolean savedIsMicrophoneMute = false; + + /** Construction */ + static AppRTCAudioManager create(Context context) { + return new AppRTCAudioManager(context); + } + + private AppRTCAudioManager(Context context) { + Log.d(TAG, "AppRTCAudioManager"); + audioManager = ((AudioManager) context.getSystemService( + Context.AUDIO_SERVICE)); + } + + public void init() { + Log.d(TAG, "init"); + if (initialized) { + return; + } + + // Store current audio state so we can restore it when close() is called. + savedAudioMode = audioManager.getMode(); + savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); + savedIsMicrophoneMute = audioManager.isMicrophoneMute(); + + // The AppRTC demo shall always run in COMMUNICATION mode since it will + // result in best possible "VoIP settings", like audio routing, volume + // control etc. + audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + + initialized = true; + } + + public void close() { + Log.d(TAG, "close"); + if (!initialized) { + return; + } + + // Restore previously stored audio states. + setSpeakerphoneOn(savedIsSpeakerPhoneOn); + setMicrophoneMute(savedIsMicrophoneMute); + audioManager.setMode(savedAudioMode); + + initialized = false; + } + + /** Sets the speaker phone mode. */ + private void setSpeakerphoneOn(boolean on) { + boolean wasOn = audioManager.isSpeakerphoneOn(); + if (wasOn == on) { + return; + } + audioManager.setSpeakerphoneOn(on); + } + + /** Sets the microphone mute state. */ + private void setMicrophoneMute(boolean on) { + boolean wasMuted = audioManager.isMicrophoneMute(); + if (wasMuted == on) { + return; + } + audioManager.setMicrophoneMute(on); + } +} diff --git a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java index ad0e2d5..3ad26af 100644 --- a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java +++ b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java @@ -34,7 +34,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Color; -import android.media.AudioManager; import android.net.Uri; import android.opengl.GLSurfaceView; import android.os.Bundle; @@ -72,6 +71,7 @@ public class AppRTCDemoActivity extends Activity private PeerConnectionClient pc; private AppRTCClient appRtcClient = new GAERTCClient(this, this); private AppRTCSignalingParameters appRtcParameters; + private AppRTCAudioManager audioManager = null; private View rootView; private View menuBar; private GLSurfaceView videoView; @@ -187,15 +187,9 @@ public class AppRTCDemoActivity extends Activity hudView.setVisibility(View.INVISIBLE); addContentView(hudView, hudLayout); - AudioManager audioManager = - ((AudioManager) getSystemService(AUDIO_SERVICE)); - // TODO(fischman): figure out how to do this Right(tm) and remove the - // suppression. - @SuppressWarnings("deprecation") - boolean isWiredHeadsetOn = audioManager.isWiredHeadsetOn(); - audioManager.setMode(isWiredHeadsetOn ? - AudioManager.MODE_IN_CALL : AudioManager.MODE_IN_COMMUNICATION); - audioManager.setSpeakerphoneOn(!isWiredHeadsetOn); + // Create and audio manager that will take care of audio routing, + // audio modes, audio device enumeration etc. + audioManager = AppRTCAudioManager.create(this); final Intent intent = getIntent(); Uri url = intent.getData(); @@ -253,6 +247,10 @@ public class AppRTCDemoActivity extends Activity @Override protected void onDestroy() { disconnect(); + if (audioManager != null) { + audioManager.close(); + audioManager = null; + } super.onDestroy(); } @@ -360,6 +358,12 @@ public class AppRTCDemoActivity extends Activity // All events are called from UI thread. @Override public void onConnectedToRoom(final AppRTCSignalingParameters params) { + if (audioManager != null) { + // Store existing audio settings and change audio mode to + // MODE_IN_COMMUNICATION for best possible VoIP performance. + logAndToast("Initializing the audio manager..."); + audioManager.init(); + } appRtcParameters = params; abortUnless(PeerConnectionFactory.initializeAndroidGlobals( this, true, true, VideoRendererGui.getEGLContext()), diff --git a/libjingle_examples.gyp b/libjingle_examples.gyp index d0f1747..f7ce53b 100755 --- a/libjingle_examples.gyp +++ b/libjingle_examples.gyp @@ -344,6 +344,7 @@ 'examples/android/res/values/arrays.xml', 'examples/android/res/values/strings.xml', 'examples/android/res/xml/preferences.xml', + 'examples/android/src/org/appspot/apprtc/AppRTCAudioManager.java', 'examples/android/src/org/appspot/apprtc/AppRTCClient.java', 'examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java', 'examples/android/src/org/appspot/apprtc/ConnectActivity.java', -- cgit v1.2.3 From 2cc4257b28bcc0ab6bdd6f6f67ce4b79fb6c60e1 Mon Sep 17 00:00:00 2001 From: "andresp@webrtc.org" Date: Fri, 7 Nov 2014 09:37:54 +0000 Subject: Refactor webrtcvideoengines to have the default list of supported codecs being generated in runtime. This will allow to plugin VP9 based on a field trial. R=pbos@webrtc.org, pbos, pthatcher Review URL: https://webrtc-codereview.appspot.com/27949004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7658 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/constants.h | 4 +- media/webrtc/webrtcvideoengine.cc | 147 +++++++++++++++++++------------------ media/webrtc/webrtcvideoengine.h | 22 +++--- media/webrtc/webrtcvideoengine2.cc | 140 ++++++++++------------------------- 4 files changed, 127 insertions(+), 186 deletions(-) diff --git a/media/webrtc/constants.h b/media/webrtc/constants.h index 5390c0d..821a41f 100755 --- a/media/webrtc/constants.h +++ b/media/webrtc/constants.h @@ -35,7 +35,9 @@ extern const int kVideoRtpBufferSize; extern const char kVp8CodecName[]; extern const char kH264CodecName[]; -extern const int kDefaultFramerate; +extern const int kDefaultVideoMaxWidth; +extern const int kDefaultVideoMaxHeight; +extern const int kDefaultVideoMaxFramerate; extern const int kMinVideoBitrate; extern const int kStartVideoBitrate; extern const int kMaxVideoBitrate; diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc index 6dacadd..46d316f 100644 --- a/media/webrtc/webrtcvideoengine.cc +++ b/media/webrtc/webrtcvideoengine.cc @@ -55,6 +55,7 @@ #include "webrtc/base/basictypes.h" #include "webrtc/base/buffer.h" #include "webrtc/base/byteorder.h" +#include "webrtc/base/checks.h" #include "webrtc/base/common.h" #include "webrtc/base/cpumonitor.h" #include "webrtc/base/logging.h" @@ -106,7 +107,10 @@ const int kVideoRtpBufferSize = 65536; const char kVp8CodecName[] = "VP8"; -const int kDefaultFramerate = 30; +// TODO(ronghuawu): Change to 640x360. +const int kDefaultVideoMaxWidth = 640; +const int kDefaultVideoMaxHeight = 400; +const int kDefaultVideoMaxFramerate = 30; const int kMinVideoBitrate = 30; const int kStartVideoBitrate = 300; const int kMaxVideoBitrate = 2000; @@ -176,15 +180,57 @@ static const bool kNotSending = false; static const rtc::DiffServCodePoint kVideoDscpValue = rtc::DSCP_AF41; -static bool IsNackEnabled(const VideoCodec& codec) { - return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, - kParamValueEmpty)); +bool IsNackEnabled(const VideoCodec& codec) { + return codec.HasFeedbackParam( + FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); +} + +bool IsRembEnabled(const VideoCodec& codec) { + return codec.HasFeedbackParam( + FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); +} + +void AddDefaultFeedbackParams(VideoCodec* codec) { + codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); + codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); + codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); + codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); +} + +bool CodecNameMatches(const std::string& name1, const std::string& name2) { + return _stricmp(name1.c_str(), name2.c_str()) == 0; +} + +static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, + const char* name) { + VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth, + kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0); + AddDefaultFeedbackParams(&codec); + return codec; +} + +static VideoCodec MakeVideoCodec(int payload_type, const char* name) { + return VideoCodec(payload_type, name, 0, 0, 0, 0); +} + +static VideoCodec MakeRtxCodec(int payload_type, int associated_payload_type) { + return VideoCodec::CreateRtxCodec(payload_type, associated_payload_type); +} + +bool CodecIsInternallySupported(const std::string& codec_name) { + if (CodecNameMatches(codec_name, kVp8CodecName)) { + return true; + } + return false; } -// Returns true if Receiver Estimated Max Bitrate is enabled. -static bool IsRembEnabled(const VideoCodec& codec) { - return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamRemb, - kParamValueEmpty)); +std::vector DefaultVideoCodecList() { + std::vector codecs; + codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(100, kVp8CodecName)); + codecs.push_back(MakeRtxCodec(96, 100)); + codecs.push_back(MakeVideoCodec(116, kRedCodecName)); + codecs.push_back(MakeVideoCodec(117, kUlpfecCodecName)); + return codecs; } struct FlushBlackFrameData : public rtc::MessageData { @@ -923,18 +969,6 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> { AdaptFormatType adapt_format_type_; }; -const WebRtcVideoEngine::VideoCodecPref - WebRtcVideoEngine::kVideoCodecPrefs[] = { - {kVp8CodecName, 100, -1, 0}, - {kRedCodecName, 116, -1, 1}, - {kUlpfecCodecName, 117, -1, 2}, - {kRtxCodecName, 96, 100, 3}, -}; - -const VideoFormatPod WebRtcVideoEngine::kDefaultMaxVideoFormat = - {640, 400, FPS_TO_INTERVAL(30), FOURCC_ANY}; -// TODO(ronghuawu): Change to 640x360. - static bool GetCpuOveruseOptions(const VideoOptions& options, webrtc::CpuOveruseOptions* overuse_options) { int underuse_threshold = 0; @@ -1018,20 +1052,14 @@ void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper, LOG_RTCERR1(SetTraceCallback, this); } + default_video_codec_list_ = DefaultVideoCodecList(); + // Set default quality levels for our supported codecs. We override them here // if we know your cpu performance is low, and they can be updated explicitly // by calling SetDefaultCodec. For example by a flute preference setting, or // by the server with a jec in response to our reported system info. - VideoCodec max_codec(kVideoCodecPrefs[0].payload_type, - kVideoCodecPrefs[0].name, - kDefaultMaxVideoFormat.width, - kDefaultMaxVideoFormat.height, - VideoFormat::IntervalToFps( - kDefaultMaxVideoFormat.interval), - 0); - if (!SetDefaultCodec(max_codec)) { - LOG(LS_ERROR) << "Failed to initialize list of supported codec types"; - } + CHECK(SetDefaultCodec(default_video_codec_list_.front())) + << "Failed to initialize list of supported codec types."; // Consider jitter, packet loss, etc when rendering. This will // theoretically make rendering more smooth. @@ -1214,13 +1242,12 @@ bool WebRtcVideoEngine::FindCodec(const VideoCodec& in) { return true; } } - for (size_t j = 0; j < ARRAY_SIZE(kVideoCodecPrefs); ++j) { - VideoCodec codec(kVideoCodecPrefs[j].payload_type, - kVideoCodecPrefs[j].name, 0, 0, 0, 0); - if (codec.Matches(in)) { + for (size_t j = 0; j != default_video_codec_list_.size(); ++j) { + if (default_video_codec_list_[j].Matches(in)) { return true; } } + return false; } @@ -1428,17 +1455,6 @@ void WebRtcVideoEngine::SetTraceOptions(const std::string& options) { } } -static void AddDefaultFeedbackParams(VideoCodec* codec) { - const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); - codec->AddFeedbackParam(kFir); - const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); - codec->AddFeedbackParam(kNack); - const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); - codec->AddFeedbackParam(kPli); - const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); - codec->AddFeedbackParam(kRemb); -} - // Rebuilds the codec list to be only those that are less intensive // than the specified codec. Prefers internal codec over external with // higher preference field. @@ -1448,27 +1464,17 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) { video_codecs_.clear(); - bool found = false; std::set internal_codec_names; - for (size_t i = 0; i < ARRAY_SIZE(kVideoCodecPrefs); ++i) { - const VideoCodecPref& pref(kVideoCodecPrefs[i]); - if (!found) - found = (in_codec.name == pref.name); - if (found) { - VideoCodec codec(pref.payload_type, pref.name, - in_codec.width, in_codec.height, in_codec.framerate, - static_cast(ARRAY_SIZE(kVideoCodecPrefs) - i)); - if (_stricmp(kVp8CodecName, codec.name.c_str()) == 0) { - AddDefaultFeedbackParams(&codec); - } - if (pref.associated_payload_type != -1) { - codec.SetParam(kCodecParamAssociatedPayloadType, - pref.associated_payload_type); - } - video_codecs_.push_back(codec); - internal_codec_names.insert(codec.name); - } + for (size_t i = 0; i != default_video_codec_list_.size(); ++i) { + VideoCodec codec = default_video_codec_list_[i]; + codec.width = in_codec.width; + codec.height = in_codec.height; + codec.framerate = in_codec.framerate; + video_codecs_.push_back(codec); + + internal_codec_names.insert(codec.name); } + if (encoder_factory_) { const std::vector& codecs = encoder_factory_->codecs(); @@ -1476,8 +1482,6 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) { bool is_internal_codec = internal_codec_names.find(codecs[i].name) != internal_codec_names.end(); if (!is_internal_codec) { - if (!found) - found = (in_codec.name == codecs[i].name); VideoCodec codec( GetExternalVideoPayloadType(static_cast(i)), codecs[i].name, @@ -1492,7 +1496,6 @@ bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) { } } } - ASSERT(found); return true; } @@ -1598,12 +1601,10 @@ void WebRtcVideoEngine::SetExternalEncoderFactory( encoder_factory_ = encoder_factory; // Rebuild codec list while reapplying the current default codec format. - VideoCodec max_codec(kVideoCodecPrefs[0].payload_type, - kVideoCodecPrefs[0].name, - video_codecs_[0].width, - video_codecs_[0].height, - video_codecs_[0].framerate, - 0); + VideoCodec max_codec = default_video_codec_list_[0]; + max_codec.width = video_codecs_[0].width; + max_codec.height = video_codecs_[0].height; + max_codec.framerate = video_codecs_[0].framerate; if (!RebuildCodecList(max_codec)) { LOG(LS_ERROR) << "Failed to initialize list of supported codec types"; } diff --git a/media/webrtc/webrtcvideoengine.h b/media/webrtc/webrtcvideoengine.h index d577b4b..db091af 100644 --- a/media/webrtc/webrtcvideoengine.h +++ b/media/webrtc/webrtcvideoengine.h @@ -85,6 +85,15 @@ class WebRtcVoiceEngine; struct CapturedFrame; struct Device; +// This set of methods is declared here for the sole purpose of sharing code +// between webrtc video engine v1 and v2. +std::vector DefaultVideoCodecList(); +bool CodecNameMatches(const std::string& name1, const std::string& name2); +bool CodecIsInternallySupported(const std::string& codec_name); +bool IsNackEnabled(const VideoCodec& codec); +bool IsRembEnabled(const VideoCodec& codec); +void AddDefaultFeedbackParams(VideoCodec* codec); + class WebRtcVideoEngine : public sigslot::has_slots<>, public webrtc::TraceCallback { public: @@ -187,18 +196,6 @@ class WebRtcVideoEngine : public sigslot::has_slots<>, private: typedef std::vector VideoChannels; - struct VideoCodecPref { - const char* name; - int payload_type; - // For RTX, this field is the payload-type that RTX applies to. - // For other codecs, it should be set to -1. - int associated_payload_type; - int pref; - }; - - static const VideoCodecPref kVideoCodecPrefs[]; - static const VideoFormatPod kVideoFormats[]; - static const VideoFormatPod kDefaultMaxVideoFormat; void Construct(ViEWrapper* vie_wrapper, ViETraceWrapper* tracing, @@ -225,6 +222,7 @@ class WebRtcVideoEngine : public sigslot::has_slots<>, WebRtcVideoEncoderFactory* encoder_factory_; WebRtcVideoDecoderFactory* decoder_factory_; std::vector video_codecs_; + std::vector default_video_codec_list_; std::vector rtp_header_extensions_; VideoFormat default_codec_format_; diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index a641a58..8d53f17 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -36,6 +36,7 @@ #include "talk/media/base/videorenderer.h" #include "talk/media/webrtc/constants.h" #include "talk/media/webrtc/webrtcvideocapturer.h" +#include "talk/media/webrtc/webrtcvideoengine.h" #include "talk/media/webrtc/webrtcvideoframe.h" #include "talk/media/webrtc/webrtcvoiceengine.h" #include "webrtc/base/buffer.h" @@ -51,26 +52,6 @@ namespace cricket { namespace { - -static bool CodecNameMatches(const std::string& name1, - const std::string& name2) { - return _stricmp(name1.c_str(), name2.c_str()) == 0; -} - -const char* kInternallySupportedCodecs[] = { - kVp8CodecName, -}; - -// True if codec is supported by a software implementation that's always -// available. -static bool CodecIsInternallySupported(const std::string& codec_name) { - for (size_t i = 0; i < ARRAY_SIZE(kInternallySupportedCodecs); ++i) { - if (CodecNameMatches(codec_name, kInternallySupportedCodecs[i])) - return true; - } - return false; -} - static std::string CodecVectorToString(const std::vector& codecs) { std::stringstream out; out << '{'; @@ -116,6 +97,29 @@ static std::string RtpExtensionsToString( return out.str(); } +// Merges two fec configs and logs an error if a conflict arises +// such that merging in diferent order would trigger a diferent output. +static void MergeFecConfig(const webrtc::FecConfig& other, + webrtc::FecConfig* output) { + if (other.ulpfec_payload_type != -1) { + if (output->ulpfec_payload_type != -1 && + output->ulpfec_payload_type != other.ulpfec_payload_type) { + LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " + << output->ulpfec_payload_type << " and " + << other.ulpfec_payload_type; + } + output->ulpfec_payload_type = other.ulpfec_payload_type; + } + if (other.red_payload_type != -1) { + if (output->red_payload_type != -1 && + output->red_payload_type != other.red_payload_type) { + LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " + << output->red_payload_type << " and " + << other.red_payload_type; + } + output->red_payload_type = other.red_payload_type; + } +} } // namespace // This constant is really an on/off, lower-level configurable NACK history @@ -135,19 +139,8 @@ static const int kExternalVideoPayloadTypeBase = 120; static const size_t kMaxExternalVideoCodecs = 8; #endif -struct VideoCodecPref { - int payload_type; - int width; - int height; - const char* name; - int rtx_payload_type; -} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96}; - const char kH264CodecName[] = "H264"; -VideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1}; -VideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1}; - static bool FindFirstMatchingCodec(const std::vector& codecs, const VideoCodec& requested_codec, VideoCodec* matching_codec) { @@ -160,59 +153,6 @@ static bool FindFirstMatchingCodec(const std::vector& codecs, return false; } -static void AddDefaultFeedbackParams(VideoCodec* codec) { - const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); - codec->AddFeedbackParam(kFir); - const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); - codec->AddFeedbackParam(kNack); - const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); - codec->AddFeedbackParam(kPli); - const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); - codec->AddFeedbackParam(kRemb); -} - -static bool IsNackEnabled(const VideoCodec& codec) { - return codec.HasFeedbackParam( - FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); -} - -static bool IsRembEnabled(const VideoCodec& codec) { - return codec.HasFeedbackParam( - FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); -} - -static VideoCodec DefaultVideoCodec() { - VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, - kDefaultVideoCodecPref.name, - kDefaultVideoCodecPref.width, - kDefaultVideoCodecPref.height, - kDefaultFramerate, - 0); - AddDefaultFeedbackParams(&default_codec); - return default_codec; -} - -static VideoCodec DefaultRedCodec() { - return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); -} - -static VideoCodec DefaultUlpfecCodec() { - return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); -} - -static std::vector DefaultVideoCodecs() { - std::vector codecs; - codecs.push_back(DefaultVideoCodec()); - codecs.push_back(DefaultRedCodec()); - codecs.push_back(DefaultUlpfecCodec()); - if (kDefaultVideoCodecPref.rtx_payload_type != -1) { - codecs.push_back( - VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, - kDefaultVideoCodecPref.payload_type)); - } - return codecs; -} - static bool ValidateRtpHeaderExtensionIds( const std::vector& extensions) { std::set extensions_used; @@ -258,7 +198,7 @@ std::vector WebRtcVideoEncoderFactory2::CreateVideoStreams( stream.width = codec.width; stream.height = codec.height; stream.max_framerate = - codec.framerate != 0 ? codec.framerate : kDefaultFramerate; + codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; int min_bitrate = kMinVideoBitrate; codec.GetParam(kCodecParamMinBitrate, &min_bitrate); @@ -350,9 +290,9 @@ void DefaultUnsignalledSsrcHandler::SetDefaultRenderer( WebRtcVideoEngine2::WebRtcVideoEngine2() : worker_thread_(NULL), voice_engine_(NULL), - default_codec_format_(kDefaultVideoCodecPref.width, - kDefaultVideoCodecPref.height, - FPS_TO_INTERVAL(kDefaultFramerate), + default_codec_format_(kDefaultVideoMaxWidth, + kDefaultVideoMaxHeight, + FPS_TO_INTERVAL(kDefaultVideoMaxFramerate), FOURCC_ANY), initialized_(false), cpu_monitor_(new rtc::CpuMonitor(NULL)), @@ -571,7 +511,7 @@ WebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { } std::vector WebRtcVideoEngine2::GetSupportedCodecs() const { - std::vector supported_codecs = DefaultVideoCodecs(); + std::vector supported_codecs = DefaultVideoCodecList(); if (external_encoder_factory_ == NULL) { return supported_codecs; @@ -1097,19 +1037,19 @@ void WebRtcVideoChannel2::ConfigureReceiverRtp( } for (size_t i = 0; i < recv_codecs_.size(); ++i) { - if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { - config->rtp.fec = recv_codecs_[i].fec; - uint32 rtx_ssrc; - if (recv_codecs_[i].rtx_payload_type != -1 && - sp.GetFidSsrc(ssrc, &rtx_ssrc)) { - config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; - config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = - recv_codecs_[i].rtx_payload_type; - } - break; - } + MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); } + for (size_t i = 0; i < recv_codecs_.size(); ++i) { + uint32 rtx_ssrc; + if (recv_codecs_[i].rtx_payload_type != -1 && + sp.GetFidSsrc(ssrc, &rtx_ssrc)) { + webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = + config->rtp.rtx[recv_codecs_[i].codec.id]; + rtx.ssrc = rtx_ssrc; + rtx.payload_type = recv_codecs_[i].rtx_payload_type; + } + } } bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { -- cgit v1.2.3 From efe932275823d38966a45310eff7a60763f06ec1 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Fri, 7 Nov 2014 10:54:43 +0000 Subject: Prevent a lot of VideoSendStream reconfigures. Checking whether we're setting the same configuration or not. Experimentally this brings down underlying reconfigures from ~20 to about 4-5. R=stefan@webrtc.org BUG=1788 Review URL: https://webrtc-codereview.appspot.com/30909004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7659 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine2.cc | 129 ++++++++++++++++++++++++------------- media/webrtc/webrtcvideoengine2.h | 19 ++++-- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index 8d53f17..5b5f12e 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -836,9 +836,16 @@ bool WebRtcVideoChannel2::SetSendCodecs(const std::vector& codecs) { return false; } - send_codec_.Set(supported_codecs.front()); LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); + VideoCodecSettings old_codec; + if (send_codec_.Get(&old_codec) && supported_codecs.front() == old_codec) { + // Using same codec, avoid reconfiguring. + return true; + } + + send_codec_.Set(supported_codecs.front()); + rtc::CritScope stream_lock(&stream_crit_); for (std::map::iterator it = send_streams_.begin(); @@ -1272,6 +1279,7 @@ bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( return false; send_rtp_extensions_ = FilterRtpExtensions(extensions); + rtc::CritScope stream_lock(&stream_crit_); for (std::map::iterator it = send_streams_.begin(); @@ -1289,8 +1297,13 @@ bool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { } bool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { - LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); + LOG(LS_INFO) << "SetOptions: " << options.ToString(); + VideoOptions old_options = options_; options_.SetAll(options); + if (options_ == old_options) { + // No new options to set. + return true; + } rtc::CritScope stream_lock(&stream_crit_); for (std::map::iterator it = send_streams_.begin(); @@ -1502,13 +1515,16 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; webrtc::I420VideoFrame black_frame; + // TODO(pbos): Base width/height on last_dimensions_. This will however + // fail the test AddRemoveCapturer which needs to be fixed to permit + // sending black frames in the same size that was previously sent. int width = format_.width; int height = format_.height; int half_width = (width + 1) / 2; black_frame.CreateEmptyFrame( width, height, width, half_width, half_width); SetWebRtcFrameToBlack(&black_frame); - SetDimensions(width, height, false); + SetDimensions(width, height, last_dimensions_.is_screencast); stream_->Input()->SwapFrame(&black_frame); } @@ -1635,13 +1651,17 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( const VideoCodecSettings& codec_settings, const VideoOptions& options) { - std::vector video_streams = - encoder_factory_->CreateVideoStreams( - codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); - if (video_streams.empty()) { + if (last_dimensions_.width == -1) { + last_dimensions_.width = codec_settings.codec.width; + last_dimensions_.height = codec_settings.codec.height; + last_dimensions_.is_screencast = false; + } + parameters_.encoder_config = + CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); + if (parameters_.encoder_config.streams.empty()) { return; } - parameters_.encoder_config.streams = video_streams; + format_ = VideoFormat(codec_settings.codec.width, codec_settings.codec.height, VideoFormat::FpsToInterval(30), @@ -1685,6 +1705,50 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( RecreateWebRtcStream(); } +webrtc::VideoEncoderConfig +WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( + const Dimensions& dimensions, + const VideoCodec& codec) const { + webrtc::VideoEncoderConfig encoder_config; + if (dimensions.is_screencast) { + int screencast_min_bitrate_kbps; + parameters_.options.screencast_min_bitrate.Get( + &screencast_min_bitrate_kbps); + encoder_config.min_transmit_bitrate_bps = + screencast_min_bitrate_kbps * 1000; + encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare; + } else { + encoder_config.min_transmit_bitrate_bps = 0; + encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo; + } + + // Restrict dimensions according to codec max. + int width = dimensions.width; + int height = dimensions.height; + if (!dimensions.is_screencast) { + if (codec.width < width) + width = codec.width; + if (codec.height < height) + height = codec.height; + } + + VideoCodec clamped_codec = codec; + clamped_codec.width = width; + clamped_codec.height = height; + + encoder_config.streams = encoder_factory_->CreateVideoStreams( + clamped_codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); + + // Conference mode screencast uses 2 temporal layers split at 100kbit. + if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && + dimensions.is_screencast && encoder_config.streams.size() == 1) { + encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); + encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( + kConferenceModeTemporalLayerBitrateBps); + } + return encoder_config; +} + void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( int width, int height, @@ -1694,56 +1758,25 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( // Configured using the same parameters, do not reconfigure. return; } + LOG(LS_INFO) << "SetDimensions: " << width << "x" << height + << (is_screencast ? " (screencast)" : " (not screencast)"); last_dimensions_.width = width; last_dimensions_.height = height; last_dimensions_.is_screencast = is_screencast; assert(!parameters_.encoder_config.streams.empty()); - LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; VideoCodecSettings codec_settings; parameters_.codec_settings.Get(&codec_settings); - // Restrict dimensions according to codec max. - if (!is_screencast) { - if (codec_settings.codec.width < width) - width = codec_settings.codec.width; - if (codec_settings.codec.height < height) - height = codec_settings.codec.height; - } - webrtc::VideoEncoderConfig encoder_config = parameters_.encoder_config; + webrtc::VideoEncoderConfig encoder_config = + CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); + encoder_config.encoder_specific_settings = encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, parameters_.options); - if (is_screencast) { - int screencast_min_bitrate_kbps; - parameters_.options.screencast_min_bitrate.Get( - &screencast_min_bitrate_kbps); - encoder_config.min_transmit_bitrate_bps = - screencast_min_bitrate_kbps * 1000; - encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare; - } else { - encoder_config.min_transmit_bitrate_bps = 0; - encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo; - } - - VideoCodec codec = codec_settings.codec; - codec.width = width; - codec.height = height; - - encoder_config.streams = encoder_factory_->CreateVideoStreams( - codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); - - // Conference mode screencast uses 2 temporal layers split at 100kbit. - if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && - is_screencast && encoder_config.streams.size() == 1) { - encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); - encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( - kConferenceModeTemporalLayerBitrateBps); - } - bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); encoder_factory_->DestroyVideoEncoderSettings( @@ -2073,6 +2106,14 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() : rtx_payload_type(-1) {} +bool WebRtcVideoChannel2::VideoCodecSettings::operator==( + const WebRtcVideoChannel2::VideoCodecSettings& other) const { + return codec == other.codec && + fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && + fec.red_payload_type == other.fec.red_payload_type && + rtx_payload_type == other.rtx_payload_type; +} + std::vector WebRtcVideoChannel2::MapCodecs(const std::vector& codecs) { assert(!codecs.empty()); diff --git a/media/webrtc/webrtcvideoengine2.h b/media/webrtc/webrtcvideoengine2.h index 68cacc0..9a5fe65 100644 --- a/media/webrtc/webrtcvideoengine2.h +++ b/media/webrtc/webrtcvideoengine2.h @@ -280,6 +280,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, struct VideoCodecSettings { VideoCodecSettings(); + bool operator ==(const VideoCodecSettings& other) const; + VideoCodec codec; webrtc::FecConfig fec; int rtx_payload_type; @@ -348,8 +350,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, bool external; }; - struct LastDimensions { - LastDimensions() : width(-1), height(-1), is_screencast(false) {} + struct Dimensions { + Dimensions() : width(-1), height(-1), is_screencast(false) {} int width; int height; bool is_screencast; @@ -357,23 +359,28 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) EXCLUSIVE_LOCKS_REQUIRED(lock_); - void DestroyVideoEncoder(AllocatedEncoder* encoder); + void DestroyVideoEncoder(AllocatedEncoder* encoder) + EXCLUSIVE_LOCKS_REQUIRED(lock_); void SetCodecAndOptions(const VideoCodecSettings& codec, const VideoOptions& options) EXCLUSIVE_LOCKS_REQUIRED(lock_); void RecreateWebRtcStream() EXCLUSIVE_LOCKS_REQUIRED(lock_); + webrtc::VideoEncoderConfig CreateVideoEncoderConfig( + const Dimensions& dimensions, + const VideoCodec& codec) const EXCLUSIVE_LOCKS_REQUIRED(lock_); void SetDimensions(int width, int height, bool is_screencast) EXCLUSIVE_LOCKS_REQUIRED(lock_); webrtc::Call* const call_; - WebRtcVideoEncoderFactory* const external_encoder_factory_; - WebRtcVideoEncoderFactory2* const encoder_factory_; + WebRtcVideoEncoderFactory* const external_encoder_factory_ + GUARDED_BY(lock_); + WebRtcVideoEncoderFactory2* const encoder_factory_ GUARDED_BY(lock_); rtc::CriticalSection lock_; webrtc::VideoSendStream* stream_ GUARDED_BY(lock_); VideoSendStreamParameters parameters_ GUARDED_BY(lock_); AllocatedEncoder allocated_encoder_ GUARDED_BY(lock_); - LastDimensions last_dimensions_ GUARDED_BY(lock_); + Dimensions last_dimensions_ GUARDED_BY(lock_); VideoCapturer* capturer_ GUARDED_BY(lock_); bool sending_ GUARDED_BY(lock_); -- cgit v1.2.3 From b3da49e39f95555c92519d7fcb42108339b2925e Mon Sep 17 00:00:00 2001 From: "perkj@webrtc.org" Date: Fri, 7 Nov 2014 11:22:06 +0000 Subject: Change dummy address to use 0.0.0.0 instead of :: This is to not break compatiblity with FF. https://code.google.com/p/chromium/issues/detail?id=430333 TBR=pthatcher@webrtc.org, juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/31979004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7661 4adac7df-926f-26a2-2b94-8c16560cd09d --- app/webrtc/webrtcsdp.cc | 6 ++++-- app/webrtc/webrtcsdp_unittest.cc | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/webrtc/webrtcsdp.cc b/app/webrtc/webrtcsdp.cc index 23b8f3d..c7b34c4 100644 --- a/app/webrtc/webrtcsdp.cc +++ b/app/webrtc/webrtcsdp.cc @@ -206,7 +206,9 @@ static const char kMediaPortRejected[] = "0"; // draft-ietf-mmusic-trickle-ice-01 // When no candidates have been gathered, set the connection // address to IP6 ::. -static const char kDummyAddress[] = "::"; +// TODO(perkj): FF can not parse IP6 ::. See http://crbug/430333 +// Use IPV4 per default. +static const char kDummyAddress[] = "0.0.0.0"; static const char kDummyPort[] = "9"; // RFC 3556 static const char kApplicationSpecificMaximum[] = "AS"; @@ -675,7 +677,7 @@ static void GetDefaultDestination( const std::vector& candidates, int component_id, std::string* port, std::string* ip, std::string* addr_type) { - *addr_type = kConnectionIpv6Addrtype; + *addr_type = kConnectionIpv4Addrtype; *port = kDummyPort; *ip = kDummyAddress; int current_preference = kPreferenceUnknown; diff --git a/app/webrtc/webrtcsdp_unittest.cc b/app/webrtc/webrtcsdp_unittest.cc index ea590db..8655487 100644 --- a/app/webrtc/webrtcsdp_unittest.cc +++ b/app/webrtc/webrtcsdp_unittest.cc @@ -213,8 +213,8 @@ static const char kSdpString[] = "t=0 0\r\n" "a=msid-semantic: WMS local_stream_1 local_stream_2\r\n" "m=audio 9 RTP/SAVPF 111 103 104\r\n" - "c=IN IP6 ::\r\n" - "a=rtcp:9 IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" @@ -234,8 +234,8 @@ static const char kSdpString[] = "a=ssrc:4 mslabel:local_stream_2\r\n" "a=ssrc:4 label:audio_track_id_2\r\n" "m=video 9 RTP/SAVPF 120\r\n" - "c=IN IP6 ::\r\n" - "a=rtcp:9 IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" "a=mid:video_content_name\r\n" "a=sendrecv\r\n" @@ -262,8 +262,8 @@ static const char kSdpString[] = static const char kSdpRtpDataChannelString[] = "m=application 9 RTP/SAVPF 101\r\n" - "c=IN IP6 ::\r\n" - "a=rtcp:9 IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" "a=mid:data_content_name\r\n" @@ -278,7 +278,7 @@ static const char kSdpRtpDataChannelString[] = static const char kSdpSctpDataChannelString[] = "m=application 9 DTLS/SCTP 5000\r\n" - "c=IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" "a=mid:data_content_name\r\n" @@ -289,7 +289,7 @@ static const char kSdpSctpDataChannelStringWithSctpPort[] = "m=application 9 DTLS/SCTP webrtc-datachannel\r\n" "a=fmtp:webrtc-datachannel max-message-size=100000\r\n" "a=sctp-port 5000\r\n" - "c=IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" "a=mid:data_content_name\r\n"; @@ -316,10 +316,10 @@ static const char kSdpConferenceString[] = "t=0 0\r\n" "a=msid-semantic: WMS\r\n" "m=audio 9 RTP/SAVPF 111 103 104\r\n" - "c=IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" "a=x-google-flag:conference\r\n" "m=video 9 RTP/SAVPF 120\r\n" - "c=IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" "a=x-google-flag:conference\r\n"; static const char kSdpSessionString[] = @@ -331,8 +331,8 @@ static const char kSdpSessionString[] = static const char kSdpAudioString[] = "m=audio 9 RTP/SAVPF 111\r\n" - "c=IN IP6 ::\r\n" - "a=rtcp:9 IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" @@ -344,8 +344,8 @@ static const char kSdpAudioString[] = static const char kSdpVideoString[] = "m=video 9 RTP/SAVPF 120\r\n" - "c=IN IP6 ::\r\n" - "a=rtcp:9 IN IP6 ::\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" "a=mid:video_content_name\r\n" "a=sendrecv\r\n" @@ -1596,7 +1596,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithDataChannelAndBandwidth) { // TODO(pthatcher): We need to temporarily allow the SDP to control // this for backwards-compatibility. Once we don't need that any // more, remove this. - InjectAfter("m=application 9 RTP/SAVPF 101\r\nc=IN IP6 ::\r\n", + InjectAfter("m=application 9 RTP/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\n", "b=AS:100\r\n", &expected_sdp); EXPECT_EQ(expected_sdp, message); -- cgit v1.2.3 From f97800413f157c911aefbf5be167dbd4806a2323 Mon Sep 17 00:00:00 2001 From: "henrik.lundin@webrtc.org" Date: Fri, 7 Nov 2014 12:25:00 +0000 Subject: Reapply "Advertise G722 as 8 kHz rather than 16 kHz"" This reverts r7653 and relands r7645. The reason for the original revert was that G722 disappeared from the SDP offer. This is now fixed. Also, a unit test was updated compared with the original change. BUG=3951 TBR=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/27089004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7662 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvoiceengine.cc | 31 +++++++++++++++++++++++++--- media/webrtc/webrtcvoiceengine.h | 1 + media/webrtc/webrtcvoiceengine_unittest.cc | 26 ++++++++++++++++++----- session/media/mediasessionclient_unittest.cc | 12 +++++------ 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/media/webrtc/webrtcvoiceengine.cc b/media/webrtc/webrtcvoiceengine.cc index 95e16e4..74b3163 100644 --- a/media/webrtc/webrtcvoiceengine.cc +++ b/media/webrtc/webrtcvoiceengine.cc @@ -74,7 +74,7 @@ static const CodecPref kCodecPrefs[] = { { "ISAC", 32000, 1, 104, true }, { "CELT", 32000, 1, 109, true }, { "CELT", 32000, 2, 110, true }, - { "G722", 16000, 1, 9, false }, + { "G722", 8000, 1, 9, false }, { "ILBC", 8000, 1, 102, false }, { "PCMU", 8000, 1, 0, false }, { "PCMA", 8000, 1, 8, false }, @@ -110,6 +110,7 @@ static const int kDefaultAudioDeviceId = 0; static const char kIsacCodecName[] = "ISAC"; static const char kL16CodecName[] = "L16"; +static const char kG722CodecName[] = "G722"; // Parameter used for NACK. // This value is equivalent to 5 seconds of audio data at 20 ms per packet. @@ -485,12 +486,24 @@ static void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); } +// Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC +// which says that G722 should be advertised as 8 kHz although it is a 16 kHz +// codec. +static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { + if (_stricmp(voe_codec->plname, kG722CodecName) == 0) { + // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine + // has changed, and this special case is no longer needed. + ASSERT(voe_codec->plfreq != new_plfreq); + voe_codec->plfreq = new_plfreq; + } +} + void WebRtcVoiceEngine::ConstructCodecs() { LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { + if (GetVoeCodec(i, voe_codec)) { // Skip uncompressed formats. if (_stricmp(voe_codec.plname, kL16CodecName) == 0) { continue; @@ -540,6 +553,15 @@ void WebRtcVoiceEngine::ConstructCodecs() { std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); } +bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst& codec) { + if (voe_wrapper_->codec()->GetCodec(index, codec) != -1) { + // Change the sample rate of G722 to 8000 to match SDP. + MaybeFixupG722(&codec, 8000); + return true; + } + return false; +} + WebRtcVoiceEngine::~WebRtcVoiceEngine() { LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { @@ -1224,7 +1246,7 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); for (int i = 0; i < ncodecs; ++i) { webrtc::CodecInst voe_codec; - if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { + if (GetVoeCodec(i, voe_codec)) { AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, voe_codec.rate, voe_codec.channels, 0); bool multi_rate = IsCodecMultiRate(voe_codec); @@ -1243,6 +1265,9 @@ bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, voe_codec.rate = in.bitrate; } + // Reset G722 sample rate to 16000 to match WebRTC. + MaybeFixupG722(&voe_codec, 16000); + // Apply codec-specific settings. if (IsIsac(codec)) { // If ISAC and an explicit bitrate is not specified, diff --git a/media/webrtc/webrtcvoiceengine.h b/media/webrtc/webrtcvoiceengine.h index f19059b..34b9f3c 100644 --- a/media/webrtc/webrtcvoiceengine.h +++ b/media/webrtc/webrtcvoiceengine.h @@ -199,6 +199,7 @@ class WebRtcVoiceEngine void Construct(); void ConstructCodecs(); + bool GetVoeCodec(int index, webrtc::CodecInst& codec); bool InitInternal(); bool EnsureSoundclipEngineInit(); void SetTraceFilter(int filter); diff --git a/media/webrtc/webrtcvoiceengine_unittest.cc b/media/webrtc/webrtcvoiceengine_unittest.cc index 5deabd2..5eb6e24 100644 --- a/media/webrtc/webrtcvoiceengine_unittest.cc +++ b/media/webrtc/webrtcvoiceengine_unittest.cc @@ -52,14 +52,16 @@ static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0); static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0); static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0); static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0); +static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0); +static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0); static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0); static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0); static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0); static const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0); static const cricket::AudioCodec* const kAudioCodecs[] = { - &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec, - &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, + &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kG722CodecVoE, + &kRedCodec, &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec, }; const char kRingbackTone[] = "RIFF____WAVE____ABCD1234"; static uint32 kSsrc1 = 0x99; @@ -770,6 +772,20 @@ TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) { EXPECT_EQ(1, voe_.GetNumSetSendCodecs()); } +// Verify that G722 is set with 16000 samples per second to WebRTC. +TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) { + EXPECT_TRUE(SetupEngine()); + int channel_num = voe_.GetLastChannel(); + std::vector codecs; + codecs.push_back(kG722CodecSdp); + EXPECT_TRUE(channel_->SetSendCodecs(codecs)); + webrtc::CodecInst gcodec; + EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); + EXPECT_STREQ("G722", gcodec.plname); + EXPECT_EQ(1, gcodec.channels); + EXPECT_EQ(16000, gcodec.plfreq); +} + // Test that if clockrate is not 48000 for opus, we fail. TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) { EXPECT_TRUE(SetupEngine()); @@ -3208,7 +3224,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(96, "G722", 16000, 0, 1, 0))); + cricket::AudioCodec(96, "G722", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(96, "red", 8000, 0, 1, 0))); EXPECT_TRUE(engine.FindCodec( @@ -3225,7 +3241,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA EXPECT_TRUE(engine.FindCodec( - cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722 + cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722 EXPECT_TRUE(engine.FindCodec( cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN // Check sample/bitrate matching. @@ -3248,7 +3264,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { EXPECT_EQ(103, it->id); } else if (it->name == "ISAC" && it->clockrate == 32000) { EXPECT_EQ(104, it->id); - } else if (it->name == "G722" && it->clockrate == 16000) { + } else if (it->name == "G722" && it->clockrate == 8000) { EXPECT_EQ(9, it->id); } else if (it->name == "telephone-event") { EXPECT_EQ(126, it->id); diff --git a/session/media/mediasessionclient_unittest.cc b/session/media/mediasessionclient_unittest.cc index 3e8a90f..eb052ef 100644 --- a/session/media/mediasessionclient_unittest.cc +++ b/session/media/mediasessionclient_unittest.cc @@ -61,7 +61,7 @@ static const cricket::AudioCodec kAudioCodecs[] = { cricket::AudioCodec(119, "ISACLC", 16000, 40000, 1, 16), cricket::AudioCodec(99, "speex", 16000, 22000, 1, 15), cricket::AudioCodec(97, "IPCMWB", 16000, 80000, 1, 14), - cricket::AudioCodec(9, "G722", 16000, 64000, 1, 13), + cricket::AudioCodec(9, "G722", 8000, 64000, 1, 13), cricket::AudioCodec(102, "iLBC", 8000, 13300, 1, 12), cricket::AudioCodec(98, "speex", 8000, 11000, 1, 11), cricket::AudioCodec(3, "GSM", 8000, 13000, 1, 10), @@ -81,7 +81,7 @@ static const cricket::AudioCodec kAudioCodecs[] = { static const cricket::AudioCodec kAudioCodecsDifferentPreference[] = { cricket::AudioCodec(104, "ISAC", 32000, -1, 1, 17), cricket::AudioCodec(97, "IPCMWB", 16000, 80000, 1, 14), - cricket::AudioCodec(9, "G722", 16000, 64000, 1, 13), + cricket::AudioCodec(9, "G722", 8000, 64000, 1, 13), cricket::AudioCodec(119, "ISACLC", 16000, 40000, 1, 16), cricket::AudioCodec(103, "ISAC", 16000, -1, 1, 18), cricket::AudioCodec(99, "speex", 16000, 22000, 1, 15), @@ -197,7 +197,7 @@ const std::string kGingleInitiate( " " \ " " \ + " id='9' name='G722' clockrate='8000' bitrate='64000' /> " \ " " \ " " \ " " \ " " \ + " id='9' name='G722' clockrate='8000'> " \ " " \ " " \ " { e = NextFromPayloadType(e); ASSERT_TRUE(e != NULL); codec = AudioCodecFromPayloadType(e); - VerifyAudioCodec(codec, 9, "G722", 16000, 64000, 1); + VerifyAudioCodec(codec, 9, "G722", 8000, 64000, 1); e = NextFromPayloadType(e); ASSERT_TRUE(e != NULL); @@ -2112,7 +2112,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> { codec = AudioCodecFromPayloadType(e); ASSERT_EQ(9, codec.id); ASSERT_EQ("G722", codec.name); - ASSERT_EQ(16000, codec.clockrate); + ASSERT_EQ(8000, codec.clockrate); ASSERT_EQ(64000, codec.bitrate); ASSERT_EQ(1, codec.channels); -- cgit v1.2.3