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

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

mercurial