content/media/webrtc/MediaEngineWebRTC.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef MEDIAENGINEWEBRTC_H_
michael@0 6 #define MEDIAENGINEWEBRTC_H_
michael@0 7
michael@0 8 #include "prcvar.h"
michael@0 9 #include "prthread.h"
michael@0 10 #include "nsIThread.h"
michael@0 11 #include "nsIRunnable.h"
michael@0 12
michael@0 13 #include "mozilla/Mutex.h"
michael@0 14 #include "mozilla/Monitor.h"
michael@0 15 #include "nsCOMPtr.h"
michael@0 16 #include "nsDOMFile.h"
michael@0 17 #include "nsThreadUtils.h"
michael@0 18 #include "DOMMediaStream.h"
michael@0 19 #include "nsDirectoryServiceDefs.h"
michael@0 20 #include "nsComponentManagerUtils.h"
michael@0 21 #include "nsRefPtrHashtable.h"
michael@0 22
michael@0 23 #include "VideoUtils.h"
michael@0 24 #include "MediaEngine.h"
michael@0 25 #include "VideoSegment.h"
michael@0 26 #include "AudioSegment.h"
michael@0 27 #include "StreamBuffer.h"
michael@0 28 #include "MediaStreamGraph.h"
michael@0 29
michael@0 30 #include "MediaEngineWrapper.h"
michael@0 31
michael@0 32 // WebRTC library includes follow
michael@0 33
michael@0 34 // Audio Engine
michael@0 35 #include "webrtc/voice_engine/include/voe_base.h"
michael@0 36 #include "webrtc/voice_engine/include/voe_codec.h"
michael@0 37 #include "webrtc/voice_engine/include/voe_hardware.h"
michael@0 38 #include "webrtc/voice_engine/include/voe_network.h"
michael@0 39 #include "webrtc/voice_engine/include/voe_audio_processing.h"
michael@0 40 #include "webrtc/voice_engine/include/voe_volume_control.h"
michael@0 41 #include "webrtc/voice_engine/include/voe_external_media.h"
michael@0 42 #include "webrtc/voice_engine/include/voe_audio_processing.h"
michael@0 43 #include "webrtc/voice_engine/include/voe_call_report.h"
michael@0 44
michael@0 45 // Video Engine
michael@0 46 #include "webrtc/video_engine/include/vie_base.h"
michael@0 47 #include "webrtc/video_engine/include/vie_codec.h"
michael@0 48 #include "webrtc/video_engine/include/vie_render.h"
michael@0 49 #include "webrtc/video_engine/include/vie_capture.h"
michael@0 50 #ifdef MOZ_B2G_CAMERA
michael@0 51 #include "CameraControlListener.h"
michael@0 52 #include "ICameraControl.h"
michael@0 53 #include "ImageContainer.h"
michael@0 54 #include "nsGlobalWindow.h"
michael@0 55 #include "prprf.h"
michael@0 56 #include "mozilla/Hal.h"
michael@0 57 #endif
michael@0 58
michael@0 59 #include "NullTransport.h"
michael@0 60 #include "AudioOutputObserver.h"
michael@0 61
michael@0 62 namespace mozilla {
michael@0 63
michael@0 64 #ifdef MOZ_B2G_CAMERA
michael@0 65 class CameraAllocateRunnable;
michael@0 66 class GetCameraNameRunnable;
michael@0 67 #endif
michael@0 68
michael@0 69 /**
michael@0 70 * The WebRTC implementation of the MediaEngine interface.
michael@0 71 *
michael@0 72 * On B2G platform, member data may accessed from different thread after construction:
michael@0 73 *
michael@0 74 * MediaThread:
michael@0 75 * mState, mImage, mWidth, mHeight, mCapability, mPrefs, mDeviceName, mUniqueId, mInitDone,
michael@0 76 * mImageContainer, mSources, mState, mImage
michael@0 77 *
michael@0 78 * MainThread:
michael@0 79 * mCaptureIndex, mLastCapture, mState, mWidth, mHeight,
michael@0 80 *
michael@0 81 * Where mWidth, mHeight, mImage are protected by mMonitor
michael@0 82 * mState is protected by mCallbackMonitor
michael@0 83 * Other variable is accessed only from single thread
michael@0 84 */
michael@0 85 class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource
michael@0 86 , public nsRunnable
michael@0 87 #ifdef MOZ_B2G_CAMERA
michael@0 88 , public CameraControlListener
michael@0 89 , public mozilla::hal::ScreenConfigurationObserver
michael@0 90 #else
michael@0 91 , public webrtc::ExternalRenderer
michael@0 92 #endif
michael@0 93 {
michael@0 94 public:
michael@0 95 #ifdef MOZ_B2G_CAMERA
michael@0 96 MediaEngineWebRTCVideoSource(int aIndex)
michael@0 97 : mCameraControl(nullptr)
michael@0 98 , mCallbackMonitor("WebRTCCamera.CallbackMonitor")
michael@0 99 , mRotation(0)
michael@0 100 , mBackCamera(false)
michael@0 101 , mCaptureIndex(aIndex)
michael@0 102 , mMonitor("WebRTCCamera.Monitor")
michael@0 103 , mWidth(0)
michael@0 104 , mHeight(0)
michael@0 105 , mInitDone(false)
michael@0 106 , mInSnapshotMode(false)
michael@0 107 , mSnapshotPath(nullptr)
michael@0 108 {
michael@0 109 mState = kReleased;
michael@0 110 Init();
michael@0 111 }
michael@0 112 #else
michael@0 113 // ViEExternalRenderer.
michael@0 114 virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
michael@0 115 virtual int DeliverFrame(unsigned char*,int, uint32_t , int64_t,
michael@0 116 void *handle);
michael@0 117 /**
michael@0 118 * Does DeliverFrame() support a null buffer and non-null handle
michael@0 119 * (video texture)?
michael@0 120 * XXX Investigate! Especially for Android/B2G
michael@0 121 */
michael@0 122 virtual bool IsTextureSupported() { return false; }
michael@0 123
michael@0 124 MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr, int aIndex)
michael@0 125 : mVideoEngine(aVideoEnginePtr)
michael@0 126 , mCaptureIndex(aIndex)
michael@0 127 , mFps(-1)
michael@0 128 , mMinFps(-1)
michael@0 129 , mMonitor("WebRTCCamera.Monitor")
michael@0 130 , mWidth(0)
michael@0 131 , mHeight(0)
michael@0 132 , mInitDone(false)
michael@0 133 , mInSnapshotMode(false)
michael@0 134 , mSnapshotPath(nullptr) {
michael@0 135 MOZ_ASSERT(aVideoEnginePtr);
michael@0 136 mState = kReleased;
michael@0 137 Init();
michael@0 138 }
michael@0 139 #endif
michael@0 140
michael@0 141 ~MediaEngineWebRTCVideoSource() { Shutdown(); }
michael@0 142
michael@0 143 virtual void GetName(nsAString&);
michael@0 144 virtual void GetUUID(nsAString&);
michael@0 145 virtual nsresult Allocate(const VideoTrackConstraintsN &aConstraints,
michael@0 146 const MediaEnginePrefs &aPrefs);
michael@0 147 virtual nsresult Deallocate();
michael@0 148 virtual nsresult Start(SourceMediaStream*, TrackID);
michael@0 149 virtual nsresult Stop(SourceMediaStream*, TrackID);
michael@0 150 virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
michael@0 151 virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
michael@0 152 bool aAgcOn, uint32_t aAGC,
michael@0 153 bool aNoiseOn, uint32_t aNoise,
michael@0 154 int32_t aPlayoutDelay) { return NS_OK; };
michael@0 155 virtual void NotifyPull(MediaStreamGraph* aGraph,
michael@0 156 SourceMediaStream *aSource,
michael@0 157 TrackID aId,
michael@0 158 StreamTime aDesiredTime,
michael@0 159 TrackTicks &aLastEndTime);
michael@0 160
michael@0 161 virtual bool IsFake() {
michael@0 162 return false;
michael@0 163 }
michael@0 164
michael@0 165 #ifndef MOZ_B2G_CAMERA
michael@0 166 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 167 #else
michael@0 168 // We are subclassed from CameraControlListener, which implements a
michael@0 169 // threadsafe reference-count for us.
michael@0 170 NS_DECL_ISUPPORTS_INHERITED
michael@0 171
michael@0 172 void OnHardwareStateChange(HardwareState aState);
michael@0 173 bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
michael@0 174 void OnError(CameraErrorContext aContext, CameraError aError);
michael@0 175 void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
michael@0 176
michael@0 177 void AllocImpl();
michael@0 178 void DeallocImpl();
michael@0 179 void StartImpl(webrtc::CaptureCapability aCapability);
michael@0 180 void StopImpl();
michael@0 181 void SnapshotImpl();
michael@0 182 void RotateImage(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
michael@0 183 void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration);
michael@0 184 #endif
michael@0 185
michael@0 186 // This runnable is for creating a temporary file on the main thread.
michael@0 187 NS_IMETHODIMP
michael@0 188 Run()
michael@0 189 {
michael@0 190 nsCOMPtr<nsIFile> tmp;
michael@0 191 nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmp));
michael@0 192 NS_ENSURE_SUCCESS(rv, rv);
michael@0 193
michael@0 194 tmp->Append(NS_LITERAL_STRING("webrtc_snapshot.jpeg"));
michael@0 195 rv = tmp->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
michael@0 196 NS_ENSURE_SUCCESS(rv, rv);
michael@0 197
michael@0 198 mSnapshotPath = new nsString();
michael@0 199 rv = tmp->GetPath(*mSnapshotPath);
michael@0 200 NS_ENSURE_SUCCESS(rv, rv);
michael@0 201
michael@0 202 return NS_OK;
michael@0 203 }
michael@0 204
michael@0 205 private:
michael@0 206 static const unsigned int KMaxDeviceNameLength = 128;
michael@0 207 static const unsigned int KMaxUniqueIdLength = 256;
michael@0 208
michael@0 209 // Initialize the needed Video engine interfaces.
michael@0 210 void Init();
michael@0 211 void Shutdown();
michael@0 212
michael@0 213 // Engine variables.
michael@0 214 #ifdef MOZ_B2G_CAMERA
michael@0 215 nsRefPtr<ICameraControl> mCameraControl;
michael@0 216 mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling
michael@0 217 nsRefPtr<nsIDOMFile> mLastCapture;
michael@0 218 int mRotation;
michael@0 219 int mCameraAngle; // See dom/base/ScreenOrientation.h
michael@0 220 bool mBackCamera;
michael@0 221 #else
michael@0 222 webrtc::VideoEngine* mVideoEngine; // Weak reference, don't free.
michael@0 223 webrtc::ViEBase* mViEBase;
michael@0 224 webrtc::ViECapture* mViECapture;
michael@0 225 webrtc::ViERender* mViERender;
michael@0 226 #endif
michael@0 227 webrtc::CaptureCapability mCapability; // Doesn't work on OS X.
michael@0 228
michael@0 229 int mCaptureIndex;
michael@0 230 int mFps; // Track rate (30 fps by default)
michael@0 231 int mMinFps; // Min rate we want to accept
michael@0 232
michael@0 233 // mMonitor protects mImage access/changes, and transitions of mState
michael@0 234 // from kStarted to kStopped (which are combined with EndTrack() and
michael@0 235 // image changes). Note that mSources is not accessed from other threads
michael@0 236 // for video and is not protected.
michael@0 237 Monitor mMonitor; // Monitor for processing WebRTC frames.
michael@0 238 int mWidth, mHeight;
michael@0 239 nsRefPtr<layers::Image> mImage;
michael@0 240 nsRefPtr<layers::ImageContainer> mImageContainer;
michael@0 241
michael@0 242 nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
michael@0 243
michael@0 244 bool mInitDone;
michael@0 245 bool mInSnapshotMode;
michael@0 246 nsString* mSnapshotPath;
michael@0 247
michael@0 248 nsString mDeviceName;
michael@0 249 nsString mUniqueId;
michael@0 250
michael@0 251 void ChooseCapability(const VideoTrackConstraintsN &aConstraints,
michael@0 252 const MediaEnginePrefs &aPrefs);
michael@0 253
michael@0 254 void GuessCapability(const VideoTrackConstraintsN &aConstraints,
michael@0 255 const MediaEnginePrefs &aPrefs);
michael@0 256 };
michael@0 257
michael@0 258 class MediaEngineWebRTCAudioSource : public MediaEngineAudioSource,
michael@0 259 public webrtc::VoEMediaProcess
michael@0 260 {
michael@0 261 public:
michael@0 262 MediaEngineWebRTCAudioSource(webrtc::VoiceEngine* aVoiceEnginePtr, int aIndex,
michael@0 263 const char* name, const char* uuid)
michael@0 264 : mVoiceEngine(aVoiceEnginePtr)
michael@0 265 , mMonitor("WebRTCMic.Monitor")
michael@0 266 , mCapIndex(aIndex)
michael@0 267 , mChannel(-1)
michael@0 268 , mInitDone(false)
michael@0 269 , mStarted(false)
michael@0 270 , mSamples(0)
michael@0 271 , mEchoOn(false), mAgcOn(false), mNoiseOn(false)
michael@0 272 , mEchoCancel(webrtc::kEcDefault)
michael@0 273 , mAGC(webrtc::kAgcDefault)
michael@0 274 , mNoiseSuppress(webrtc::kNsDefault)
michael@0 275 , mPlayoutDelay(0)
michael@0 276 , mNullTransport(nullptr) {
michael@0 277 MOZ_ASSERT(aVoiceEnginePtr);
michael@0 278 mState = kReleased;
michael@0 279 mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
michael@0 280 mDeviceUUID.Assign(NS_ConvertUTF8toUTF16(uuid));
michael@0 281 Init();
michael@0 282 }
michael@0 283 ~MediaEngineWebRTCAudioSource() { Shutdown(); }
michael@0 284
michael@0 285 virtual void GetName(nsAString&);
michael@0 286 virtual void GetUUID(nsAString&);
michael@0 287
michael@0 288 virtual nsresult Allocate(const AudioTrackConstraintsN &aConstraints,
michael@0 289 const MediaEnginePrefs &aPrefs);
michael@0 290 virtual nsresult Deallocate();
michael@0 291 virtual nsresult Start(SourceMediaStream*, TrackID);
michael@0 292 virtual nsresult Stop(SourceMediaStream*, TrackID);
michael@0 293 virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
michael@0 294 virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
michael@0 295 bool aAgcOn, uint32_t aAGC,
michael@0 296 bool aNoiseOn, uint32_t aNoise,
michael@0 297 int32_t aPlayoutDelay);
michael@0 298
michael@0 299 virtual void NotifyPull(MediaStreamGraph* aGraph,
michael@0 300 SourceMediaStream *aSource,
michael@0 301 TrackID aId,
michael@0 302 StreamTime aDesiredTime,
michael@0 303 TrackTicks &aLastEndTime);
michael@0 304
michael@0 305 virtual bool IsFake() {
michael@0 306 return false;
michael@0 307 }
michael@0 308
michael@0 309 // VoEMediaProcess.
michael@0 310 void Process(int channel, webrtc::ProcessingTypes type,
michael@0 311 int16_t audio10ms[], int length,
michael@0 312 int samplingFreq, bool isStereo);
michael@0 313
michael@0 314 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 315
michael@0 316 private:
michael@0 317 static const unsigned int KMaxDeviceNameLength = 128;
michael@0 318 static const unsigned int KMaxUniqueIdLength = 256;
michael@0 319
michael@0 320 void Init();
michael@0 321 void Shutdown();
michael@0 322
michael@0 323 webrtc::VoiceEngine* mVoiceEngine;
michael@0 324 ScopedCustomReleasePtr<webrtc::VoEBase> mVoEBase;
michael@0 325 ScopedCustomReleasePtr<webrtc::VoEExternalMedia> mVoERender;
michael@0 326 ScopedCustomReleasePtr<webrtc::VoENetwork> mVoENetwork;
michael@0 327 ScopedCustomReleasePtr<webrtc::VoEAudioProcessing> mVoEProcessing;
michael@0 328 ScopedCustomReleasePtr<webrtc::VoECallReport> mVoECallReport;
michael@0 329
michael@0 330 // mMonitor protects mSources[] access/changes, and transitions of mState
michael@0 331 // from kStarted to kStopped (which are combined with EndTrack()).
michael@0 332 // mSources[] is accessed from webrtc threads.
michael@0 333 Monitor mMonitor;
michael@0 334 nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
michael@0 335
michael@0 336 int mCapIndex;
michael@0 337 int mChannel;
michael@0 338 TrackID mTrackID;
michael@0 339 bool mInitDone;
michael@0 340 bool mStarted;
michael@0 341 int mSamples; // int to avoid conversions when comparing/etc to samplingFreq & length
michael@0 342
michael@0 343 nsString mDeviceName;
michael@0 344 nsString mDeviceUUID;
michael@0 345
michael@0 346 bool mEchoOn, mAgcOn, mNoiseOn;
michael@0 347 webrtc::EcModes mEchoCancel;
michael@0 348 webrtc::AgcModes mAGC;
michael@0 349 webrtc::NsModes mNoiseSuppress;
michael@0 350 int32_t mPlayoutDelay;
michael@0 351
michael@0 352 NullTransport *mNullTransport;
michael@0 353 };
michael@0 354
michael@0 355 class MediaEngineWebRTC : public MediaEngine
michael@0 356 {
michael@0 357 public:
michael@0 358 MediaEngineWebRTC(MediaEnginePrefs &aPrefs);
michael@0 359
michael@0 360 // Clients should ensure to clean-up sources video/audio sources
michael@0 361 // before invoking Shutdown on this class.
michael@0 362 void Shutdown();
michael@0 363
michael@0 364 virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
michael@0 365 virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
michael@0 366
michael@0 367 private:
michael@0 368 ~MediaEngineWebRTC() {
michael@0 369 Shutdown();
michael@0 370 #ifdef MOZ_B2G_CAMERA
michael@0 371 AsyncLatencyLogger::Get()->Release();
michael@0 372 #endif
michael@0 373 // XXX
michael@0 374 gFarendObserver = nullptr;
michael@0 375 }
michael@0 376
michael@0 377 Mutex mMutex;
michael@0 378 // protected with mMutex:
michael@0 379
michael@0 380 webrtc::VideoEngine* mVideoEngine;
michael@0 381 webrtc::VoiceEngine* mVoiceEngine;
michael@0 382
michael@0 383 // Need this to avoid unneccesary WebRTC calls while enumerating.
michael@0 384 bool mVideoEngineInit;
michael@0 385 bool mAudioEngineInit;
michael@0 386 bool mHasTabVideoSource;
michael@0 387
michael@0 388 // Store devices we've already seen in a hashtable for quick return.
michael@0 389 // Maps UUID to MediaEngineSource (one set for audio, one for video).
michael@0 390 nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCVideoSource > mVideoSources;
michael@0 391 nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources;
michael@0 392 };
michael@0 393
michael@0 394 }
michael@0 395
michael@0 396 #endif /* NSMEDIAENGINEWEBRTC_H_ */

mercurial