diff options
Diffstat (limited to 'dom/media/systemservices/CamerasParent.h')
-rw-r--r-- | dom/media/systemservices/CamerasParent.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/dom/media/systemservices/CamerasParent.h b/dom/media/systemservices/CamerasParent.h new file mode 100644 index 000000000..2c1869410 --- /dev/null +++ b/dom/media/systemservices/CamerasParent.h @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et ft=cpp : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_CamerasParent_h +#define mozilla_CamerasParent_h + +#include "nsIObserver.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/camera/PCamerasParent.h" +#include "mozilla/ipc/Shmem.h" +#include "mozilla/ShmemPool.h" +#include "mozilla/Atomics.h" + +// conflicts with #include of scoped_ptr.h +#undef FF +#include "webrtc/common.h" +// Video Engine +#include "webrtc/video_engine/include/vie_base.h" +#include "webrtc/video_engine/include/vie_capture.h" +#include "webrtc/video_engine/include/vie_render.h" +#include "CamerasChild.h" + +#include "base/thread.h" + +namespace mozilla { +namespace camera { + +class CamerasParent; + +class CallbackHelper : public webrtc::ExternalRenderer +{ +public: + CallbackHelper(CaptureEngine aCapEng, int aCapId, CamerasParent *aParent) + : mCapEngine(aCapEng), mCapturerId(aCapId), mParent(aParent) {}; + + // ViEExternalRenderer implementation. These callbacks end up + // running on the VideoCapture thread. + virtual int FrameSizeChange(unsigned int w, unsigned int h, + unsigned int streams) override; + virtual int DeliverFrame(unsigned char* buffer, + size_t size, + uint32_t time_stamp, + int64_t ntp_time, + int64_t render_time, + void *handle) override; + virtual int DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) override; + virtual bool IsTextureSupported() override { return false; }; + + friend CamerasParent; + +private: + CaptureEngine mCapEngine; + int mCapturerId; + CamerasParent *mParent; +}; + +class EngineHelper +{ +public: + EngineHelper() : + mEngine(nullptr), mPtrViEBase(nullptr), mPtrViECapture(nullptr), + mPtrViERender(nullptr), mEngineIsRunning(false) {}; + + webrtc::VideoEngine *mEngine; + webrtc::ViEBase *mPtrViEBase; + webrtc::ViECapture *mPtrViECapture; + webrtc::ViERender *mPtrViERender; + + // The webrtc code keeps a reference to this one. + webrtc::Config mConfig; + + // Engine alive + bool mEngineIsRunning; +}; + +class InputObserver : public webrtc::ViEInputObserver +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InputObserver) + + explicit InputObserver(CamerasParent* aParent) + : mParent(aParent) {}; + virtual void DeviceChange(); + + friend CamerasParent; + +private: + ~InputObserver() {} + + RefPtr<CamerasParent> mParent; +}; + +class CamerasParent : public PCamerasParent, + public nsIObserver +{ + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + +public: + static already_AddRefed<CamerasParent> Create(); + + // Messages received form the child. These run on the IPC/PBackground thread. + virtual bool RecvAllocateCaptureDevice(const CaptureEngine&, const nsCString&, + const nsCString&) override; + virtual bool RecvReleaseCaptureDevice(const CaptureEngine&, + const int&) override; + virtual bool RecvNumberOfCaptureDevices(const CaptureEngine&) override; + virtual bool RecvNumberOfCapabilities(const CaptureEngine&, + const nsCString&) override; + virtual bool RecvGetCaptureCapability(const CaptureEngine&, const nsCString&, + const int&) override; + virtual bool RecvGetCaptureDevice(const CaptureEngine&, const int&) override; + virtual bool RecvStartCapture(const CaptureEngine&, const int&, + const CaptureCapability&) override; + virtual bool RecvStopCapture(const CaptureEngine&, const int&) override; + virtual bool RecvReleaseFrame(mozilla::ipc::Shmem&&) override; + virtual bool RecvAllDone() override; + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + virtual bool RecvEnsureInitialized(const CaptureEngine&) override; + + nsIThread* GetBackgroundThread() { return mPBackgroundThread; }; + bool IsShuttingDown() { return !mChildIsAlive + || mDestroyed + || !mWebRTCAlive; }; + ShmemBuffer GetBuffer(size_t aSize); + + // helper to forward to the PBackground thread + int DeliverFrameOverIPC(CaptureEngine capEng, + int cap_id, + ShmemBuffer buffer, + unsigned char* altbuffer, + size_t size, + uint32_t time_stamp, + int64_t ntp_time, + int64_t render_time); + + + CamerasParent(); + +protected: + virtual ~CamerasParent(); + + // We use these helpers for shutdown and for the respective IPC commands. + void StopCapture(const CaptureEngine& aCapEngine, const int& capnum); + int ReleaseCaptureDevice(const CaptureEngine& aCapEngine, const int& capnum); + + bool SetupEngine(CaptureEngine aCapEngine); + bool EnsureInitialized(int aEngine); + void CloseEngines(); + void StopIPC(); + void StopVideoCapture(); + // Can't take already_AddRefed because it can fail in stupid ways. + nsresult DispatchToVideoCaptureThread(Runnable* event); + + EngineHelper mEngines[CaptureEngine::MaxEngine]; + nsTArray<CallbackHelper*> mCallbacks; + + // image buffers + mozilla::ShmemPool mShmemPool; + + // PBackground parent thread + nsCOMPtr<nsIThread> mPBackgroundThread; + + // Monitors creation of the thread below + Monitor mThreadMonitor; + + // video processing thread - where webrtc.org capturer code runs + base::Thread* mVideoCaptureThread; + + // Shutdown handling + bool mChildIsAlive; + bool mDestroyed; + // Above 2 are PBackground only, but this is potentially + // read cross-thread. + mozilla::Atomic<bool> mWebRTCAlive; + nsTArray<RefPtr<InputObserver>> mObservers; +}; + +PCamerasParent* CreateCamerasParent(); + +} // namespace camera +} // namespace mozilla + +#endif // mozilla_CameraParent_h |