--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -12,16 +12,17 @@
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/Logging.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/Unused.h"
#include "MediaUtils.h"
#include "nsThreadUtils.h"
+#include "VideoCaptureUtils.h"
#undef LOG
#undef LOG_ENABLED
mozilla::LazyLogModule gCamerasChildLog("CamerasChild");
#define LOG(args) MOZ_LOG(gCamerasChildLog, mozilla::LogLevel::Debug, args)
#define LOG_ENABLED() MOZ_LOG_TEST(gCamerasChildLog, mozilla::LogLevel::Debug)
#define FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS 5000
@@ -181,28 +182,16 @@ CamerasChild::RecvReplySuccess(void)
LOG((__PRETTY_FUNCTION__));
MonitorAutoLock monitor(mReplyMonitor);
mReceivedReply = true;
mReplySuccess = true;
monitor.Notify();
return IPC_OK();
}
-mozilla::ipc::IPCResult
-CamerasChild::RecvReplyNumberOfCapabilities(const int& numdev)
-{
- LOG((__PRETTY_FUNCTION__));
- MonitorAutoLock monitor(mReplyMonitor);
- mReceivedReply = true;
- mReplySuccess = true;
- mReplyInteger = numdev;
- monitor.Notify();
- return IPC_OK();
-}
-
// Helper function to dispatch calls to the IPC Thread and
// CamerasChild object. Takes the needed locks and dispatches.
// Takes a "failed" value and a reference to the output variable
// as parameters, will return the right one depending on whether
// dispatching succeeded.
template <class T = int>
class LockAndDispatch
{
@@ -273,31 +262,16 @@ CamerasChild::DispatchToParent(nsIRunnab
} while (!mReceivedReply && mIPCIsAlive);
if (!mReplySuccess) {
return false;
}
return true;
}
int
-CamerasChild::NumberOfCapabilities(CaptureEngine aCapEngine,
- const char* deviceUniqueIdUTF8)
-{
- LOG((__PRETTY_FUNCTION__));
- LOG(("NumberOfCapabilities for %s", deviceUniqueIdUTF8));
- nsCString unique_id(deviceUniqueIdUTF8);
- nsCOMPtr<nsIRunnable> runnable =
- mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString>
- (this, &CamerasChild::SendNumberOfCapabilities, aCapEngine, unique_id);
- LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
- LOG(("Capture capability count: %d", dispatcher.ReturnValue()));
- return dispatcher.ReturnValue();
-}
-
-int
CamerasChild::NumberOfCaptureDevices(CaptureEngine aCapEngine)
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
mozilla::NewNonOwningRunnableMethod<CaptureEngine>
(this, &CamerasChild::SendNumberOfCaptureDevices, aCapEngine);
LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
@@ -324,47 +298,48 @@ CamerasChild::EnsureInitialized(CaptureE
mozilla::NewNonOwningRunnableMethod<CaptureEngine>
(this, &CamerasChild::SendEnsureInitialized, aCapEngine);
LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
return dispatcher.ReturnValue();
}
int
-CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
- const char* unique_idUTF8,
- const unsigned int capability_number,
- webrtc::VideoCaptureCapability& capability)
+CamerasChild::GetCaptureCapabilities(
+ CaptureEngine aCapEngine,
+ const char* unique_idUTF8,
+ nsTArray<webrtc::VideoCaptureCapability>& capabilityList)
{
- LOG(("GetCaptureCapability: %s %d", unique_idUTF8, capability_number));
+ LOG(("GetCaptureCapability: %s", unique_idUTF8));
nsCString unique_id(unique_idUTF8);
nsCOMPtr<nsIRunnable> runnable =
- mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString, unsigned int>
- (this, &CamerasChild::SendGetCaptureCapability, aCapEngine, unique_id, capability_number);
+ mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString>
+ (this, &CamerasChild::SendGetCaptureCapabilities, aCapEngine, unique_id);
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
- capability = mReplyCapability;
+ capabilityList.Clear();
+ capabilityList.SwapElements(mReplyCapabilities);
}
return dispatcher.ReturnValue();
}
mozilla::ipc::IPCResult
-CamerasChild::RecvReplyGetCaptureCapability(const VideoCaptureCapability& ipcCapability)
+CamerasChild::RecvReplyGetCaptureCapabilities(
+ nsTArray<VideoCaptureCapability>&& ipcCapabilityList)
{
LOG((__PRETTY_FUNCTION__));
MonitorAutoLock monitor(mReplyMonitor);
mReceivedReply = true;
mReplySuccess = true;
- mReplyCapability.width = ipcCapability.width();
- mReplyCapability.height = ipcCapability.height();
- mReplyCapability.maxFPS = ipcCapability.maxFPS();
- mReplyCapability.expectedCaptureDelay = ipcCapability.expectedCaptureDelay();
- mReplyCapability.rawType = static_cast<webrtc::RawVideoType>(ipcCapability.rawType());
- mReplyCapability.codecType = static_cast<webrtc::VideoCodecType>(ipcCapability.codecType());
- mReplyCapability.interlaced = ipcCapability.interlaced();
+ mReplyCapabilities.Clear();
+ webrtc::VideoCaptureCapability capability;
+ for (auto& ipcCapability : ipcCapabilityList) {
+ VideoCaptureUtils::IpcToWebrtcCapability(ipcCapability, capability);
+ mReplyCapabilities.AppendElement(capability);
+ }
monitor.Notify();
return IPC_OK();
}
int
CamerasChild::GetCaptureDevice(CaptureEngine aCapEngine,
unsigned int list_number, char* device_nameUTF8,
const unsigned int device_nameUTF8Length,
--- a/dom/media/systemservices/CamerasChild.h
+++ b/dom/media/systemservices/CamerasChild.h
@@ -160,47 +160,48 @@ public:
const int& w, const int& h) override;
virtual mozilla::ipc::IPCResult RecvDeviceChange() override;
virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
int SetFakeDeviceChangeEvents();
// these are response messages to our outgoing requests
virtual mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
- virtual mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
virtual mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
- virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
+
+ virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapabilities(
+ nsTArray<VideoCaptureCapability>&& capabilities) override;
+
virtual mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
const nsCString& device_id,
const bool& scary) override;
virtual mozilla::ipc::IPCResult RecvReplyFailure(void) override;
virtual mozilla::ipc::IPCResult RecvReplySuccess(void) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
// the webrtc.org ViECapture calls are mirrored here, but with access
// to a specific PCameras instance to communicate over. These also
// run on the MediaManager thread
int NumberOfCaptureDevices(CaptureEngine aCapEngine);
- int NumberOfCapabilities(CaptureEngine aCapEngine,
- const char* deviceUniqueIdUTF8);
int ReleaseCaptureDevice(CaptureEngine aCapEngine,
const int capture_id);
int StartCapture(CaptureEngine aCapEngine,
const int capture_id, webrtc::VideoCaptureCapability& capability,
FrameRelay* func);
int StopCapture(CaptureEngine aCapEngine, const int capture_id);
int AllocateCaptureDevice(CaptureEngine aCapEngine,
const char* unique_idUTF8,
const unsigned int unique_idUTF8Length,
int& capture_id,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
- int GetCaptureCapability(CaptureEngine aCapEngine,
- const char* unique_idUTF8,
- const unsigned int capability_number,
- webrtc::VideoCaptureCapability& capability);
+ int
+ GetCaptureCapabilities(
+ CaptureEngine aCapEngine,
+ const char* unique_idUTF8,
+ nsTArray<webrtc::VideoCaptureCapability>& capabilities);
int GetCaptureDevice(CaptureEngine aCapEngine,
unsigned int list_number, char* device_nameUTF8,
const unsigned int device_nameUTF8Length,
char* unique_idUTF8,
const unsigned int unique_idUTF8Length,
bool* scary = nullptr);
void ShutdownAll();
int EnsureInitialized(CaptureEngine aCapEngine);
@@ -237,17 +238,17 @@ private:
Mutex mRequestMutex;
// Hold to wait for an async response to our calls
Monitor mReplyMonitor;
// Async response valid?
bool mReceivedReply;
// Async responses data contents;
bool mReplySuccess;
int mReplyInteger;
- webrtc::VideoCaptureCapability mReplyCapability;
+ nsTArray<webrtc::VideoCaptureCapability> mReplyCapabilities;
nsCString mReplyDeviceName;
nsCString mReplyDeviceID;
bool mReplyScary;
};
} // namespace camera
} // namespace mozilla
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -2,16 +2,17 @@
/* 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/. */
#include "CamerasParent.h"
#include "MediaEngine.h"
#include "MediaUtils.h"
+#include "VideoCaptureUtils.h"
#include "VideoFrameUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Unused.h"
#include "mozilla/Services.h"
#include "mozilla/Logging.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/PBackgroundParent.h"
@@ -478,95 +479,50 @@ CamerasParent::RecvEnsureInitialized(con
self->mPBackgroundEventTarget->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
return NS_OK;
});
DispatchToVideoCaptureThread(webrtc_runnable);
return IPC_OK();
}
mozilla::ipc::IPCResult
-CamerasParent::RecvNumberOfCapabilities(const CaptureEngine& aCapEngine,
+CamerasParent::RecvGetCaptureCapabilities(const CaptureEngine& aCapEngine,
const nsCString& unique_id)
{
- LOG((__PRETTY_FUNCTION__));
- LOG(("Getting caps for %s", unique_id.get()));
-
+ LOG(("%s uid:%s", __PRETTY_FUNCTION__, unique_id.get()));
RefPtr<CamerasParent> self(this);
RefPtr<Runnable> webrtc_runnable =
media::NewRunnableFrom([self, unique_id, aCapEngine]() -> nsresult {
- int num = -1;
+ nsTArray<VideoCaptureCapability> capabilityList;
+ int error = -1;
if (auto engine = self->EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
- num = devInfo->NumberOfCapabilities(unique_id.get());
+ if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()){
+ webrtc::VideoCaptureCapability webrtcCaps;
+ VideoCaptureCapability ipcCaps;
+ int32_t num = devInfo->NumberOfCapabilities(unique_id.get());
+ for (int32_t i = 0; i < num; i++) {
+ error = devInfo->GetCapability(unique_id.get(), num, webrtcCaps);
+ if (error) {
+ break;
+ }
+ VideoCaptureUtils::WebrtcToIpcCapability(webrtcCaps, ipcCaps);
+ capabilityList.AppendElement(ipcCaps);
+ }
}
}
RefPtr<nsIRunnable> ipc_runnable =
- media::NewRunnableFrom([self, num]() -> nsresult {
+ media::NewRunnableFrom([self, capabilityList, error]() -> nsresult {
if (self->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
- if (num < 0) {
- LOG(("RecvNumberOfCapabilities couldn't find capabilities"));
- Unused << self->SendReplyFailure();
- return NS_ERROR_FAILURE;
- } else {
- LOG(("RecvNumberOfCapabilities: %d", num));
- }
- Unused << self->SendReplyNumberOfCapabilities(num);
- return NS_OK;
- });
- self->mPBackgroundEventTarget->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
- return NS_OK;
- });
- DispatchToVideoCaptureThread(webrtc_runnable);
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-CamerasParent::RecvGetCaptureCapability(const CaptureEngine& aCapEngine,
- const nsCString& unique_id,
- const int& num)
-{
- LOG((__PRETTY_FUNCTION__));
- LOG(("RecvGetCaptureCapability: %s %d", unique_id.get(), num));
-
- RefPtr<CamerasParent> self(this);
- RefPtr<Runnable> webrtc_runnable =
- media::NewRunnableFrom([self, unique_id, aCapEngine, num]() -> nsresult {
- webrtc::VideoCaptureCapability webrtcCaps;
- int error = -1;
- if (auto engine = self->EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()){
- error = devInfo->GetCapability(unique_id.get(), num, webrtcCaps);
- }
- }
- RefPtr<nsIRunnable> ipc_runnable =
- media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
- if (self->IsShuttingDown()) {
- return NS_ERROR_FAILURE;
- }
- VideoCaptureCapability capCap(webrtcCaps.width,
- webrtcCaps.height,
- webrtcCaps.maxFPS,
- webrtcCaps.expectedCaptureDelay,
- webrtcCaps.rawType,
- webrtcCaps.codecType,
- webrtcCaps.interlaced);
- LOG(("Capability: %u %u %u %u %d %d",
- webrtcCaps.width,
- webrtcCaps.height,
- webrtcCaps.maxFPS,
- webrtcCaps.expectedCaptureDelay,
- webrtcCaps.rawType,
- webrtcCaps.codecType));
if (error) {
Unused << self->SendReplyFailure();
return NS_ERROR_FAILURE;
}
- Unused << self->SendReplyGetCaptureCapability(capCap);
+ Unused << self->SendReplyGetCaptureCapabilities(capabilityList);
return NS_OK;
});
self->mPBackgroundEventTarget->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
return NS_OK;
});
DispatchToVideoCaptureThread(webrtc_runnable);
return IPC_OK();
}
@@ -794,24 +750,17 @@ CamerasParent::RecvStartCapture(const Ca
if (self->EnsureInitialized(aCapEngine)) {
cbh = self->mCallbacks.AppendElement(
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
engine = self->mEngines[aCapEngine];
engine->WithEntry(capnum, [capnum, &engine, &error, &ipcCaps, &cbh](VideoEngine::CaptureEntry& cap) {
error = 0;
webrtc::VideoCaptureCapability capability;
- capability.width = ipcCaps.width();
- capability.height = ipcCaps.height();
- capability.maxFPS = ipcCaps.maxFPS();
- capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
- capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
- capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
- capability.interlaced = ipcCaps.interlaced();
-
+ VideoCaptureUtils::IpcToWebrtcCapability(ipcCaps, capability);
if (!error) {
error = cap.VideoCapture()->StartCapture(capability);
}
if (!error) {
engine->Startup();
cap.VideoCapture()->RegisterCaptureDataCallback(static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(*cbh));
}
});
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -85,20 +85,19 @@ public:
// Messages received form the child. These run on the IPC/PBackground thread.
virtual mozilla::ipc::IPCResult
RecvAllocateCaptureDevice(const CaptureEngine& aEngine,
const nsCString& aUnique_idUTF8,
const ipc::PrincipalInfo& aPrincipalInfo) override;
virtual mozilla::ipc::IPCResult RecvReleaseCaptureDevice(const CaptureEngine&,
const int&) override;
virtual mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
- virtual mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
- const nsCString&) override;
- virtual mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
- const int&) override;
+ virtual mozilla::ipc::IPCResult
+ RecvGetCaptureCapabilities(const CaptureEngine&, const nsCString&) override;
+
virtual mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
virtual mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
const VideoCaptureCapability&) override;
virtual mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
virtual mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
virtual mozilla::ipc::IPCResult RecvAllDone() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
--- a/dom/media/systemservices/PCameras.ipdl
+++ b/dom/media/systemservices/PCameras.ipdl
@@ -19,17 +19,16 @@ struct VideoCaptureCapability
int height;
int maxFPS;
int expectedCaptureDelay;
int rawType;
int codecType;
bool interlaced;
};
-
// IPC analog for webrtc::VideoFrame
// the described buffer is transported seperately in a Shmem
// See VideoFrameUtils.h
struct VideoFrameProperties
{
// Size of image data within the ShMem,
// the ShMem is at least this large
size_t bufferSize;
@@ -56,30 +55,27 @@ async protocol PCameras
child:
async FrameSizeChange(CaptureEngine capEngine, int cap_id, int w, int h);
// transfers ownership of |buffer| from parent to child
async DeliverFrame(CaptureEngine capEngine, int streamId,
Shmem buffer, VideoFrameProperties props);
async DeviceChange();
async ReplyNumberOfCaptureDevices(int numdev);
- async ReplyNumberOfCapabilities(int numdev);
async ReplyAllocateCaptureDevice(int numdev);
- async ReplyGetCaptureCapability(VideoCaptureCapability cap);
+ async ReplyGetCaptureCapabilities(VideoCaptureCapability[] capabilities);
async ReplyGetCaptureDevice(nsCString device_name, nsCString device_id, bool scary);
async ReplyFailure();
async ReplySuccess();
async __delete__();
parent:
async NumberOfCaptureDevices(CaptureEngine engine);
- async NumberOfCapabilities(CaptureEngine engine, nsCString deviceUniqueIdUTF8);
- async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8,
- int capability_number);
+ async GetCaptureCapabilities(CaptureEngine engine, nsCString unique_idUTF8);
async GetCaptureDevice(CaptureEngine engine, int num);
async AllocateCaptureDevice(CaptureEngine engine, nsCString unique_idUTF8,
PrincipalInfo principal);
async ReleaseCaptureDevice(CaptureEngine engine, int numdev);
async StartCapture(CaptureEngine engine, int numdev, VideoCaptureCapability capability);
async StopCapture(CaptureEngine engine, int numdev);
// transfers frame back
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoCaptureUtils.cpp
@@ -0,0 +1,35 @@
+#include "VideoCaptureUtils.h"
+#ifdef MOZ_WEBRTC
+#include "mozilla/camera/PCameras.h"
+#include "webrtc/modules/video_capture/video_capture_defines.h"
+namespace mozilla {
+namespace camera {
+
+void
+VideoCaptureUtils::IpcToWebrtcCapability(
+ const VideoCaptureCapability& ipc,
+ webrtc::VideoCaptureCapability& webrtc) {
+ webrtc.width = ipc.width();
+ webrtc.height = ipc.height();
+ webrtc.maxFPS = ipc.maxFPS();
+ webrtc.expectedCaptureDelay = ipc.expectedCaptureDelay();
+ webrtc.rawType = static_cast<webrtc::RawVideoType>(ipc.rawType());
+ webrtc.codecType = static_cast<webrtc::VideoCodecType>(ipc.codecType());
+ webrtc.interlaced = ipc.interlaced();
+}
+
+void VideoCaptureUtils::WebrtcToIpcCapability(
+ const webrtc::VideoCaptureCapability& webrtc,
+ VideoCaptureCapability& ipc) {
+ ipc.width() = webrtc.width;
+ ipc.height() = webrtc.height;
+ ipc.maxFPS() = webrtc.maxFPS;
+ ipc.expectedCaptureDelay() = webrtc.expectedCaptureDelay;
+ ipc.rawType() = static_cast<int>(webrtc.rawType);
+ ipc.codecType() = static_cast<int>(webrtc.codecType);
+ ipc.interlaced() = webrtc.interlaced;
+}
+
+} // namespace camera
+} // namespace mozilla
+#endif // MOZ_WEBRTC
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoCaptureUtils.h
@@ -0,0 +1,27 @@
+#ifndef mozilla_media_VideoCaptureUtils_h
+#define mozilla_media_VideoCaptureUtils_h
+#ifdef MOZ_WEBRTC
+#include "ipc/IPCMessageUtils.h"
+
+namespace webrtc {
+ struct VideoCaptureCapability;
+}
+
+namespace mozilla {
+namespace camera {
+
+class VideoCaptureCapability;
+
+class VideoCaptureUtils {
+public:
+ static void IpcToWebrtcCapability(const VideoCaptureCapability& ipc,
+ webrtc::VideoCaptureCapability& webrtc);
+ static void WebrtcToIpcCapability(
+ const webrtc::VideoCaptureCapability& webrtc,
+ VideoCaptureCapability& ipc);
+};
+
+} // namespace camera
+} // namespace mozilla
+#endif // MOZ_WEBRTC
+#endif /* end of include guard: mozilla_media_VideoCaptureUtils_h */
--- a/dom/media/systemservices/moz.build
+++ b/dom/media/systemservices/moz.build
@@ -3,23 +3,25 @@
# 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/.
if CONFIG['MOZ_WEBRTC']:
EXPORTS += [
'CamerasChild.h',
'CamerasParent.h',
+ 'VideoCaptureUtils.h',
'VideoEngine.h',
'VideoFrameUtils.h'
]
UNIFIED_SOURCES += [
'CamerasChild.cpp',
'CamerasParent.cpp',
'ShmemPool.cpp',
+ 'VideoCaptureUtils.cpp',
'VideoEngine.cpp',
'VideoFrameUtils.cpp'
]
LOCAL_INCLUDES += [
'/media/webrtc/signaling',
'/media/webrtc/trunk',
]
if CONFIG['OS_TARGET'] == 'WINNT':
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -34,30 +34,23 @@ bool MediaEngineCameraVideoSource::Appen
// This is safe from any thread, and is safe if the track is Finished
// or Destroyed.
// This can fail if either a) we haven't added the track yet, or b)
// we've removed or finished the track.
return aSource->AppendToTrack(aID, &(segment));
}
-// Sub-classes (B2G or desktop) should overload one of both of these two methods
-// to provide capabilities
-size_t
-MediaEngineCameraVideoSource::NumCapabilities() const
+void
+MediaEngineCameraVideoSource::GetCapabilityCandidateSet(CapabilitySet& aOut) const
{
- return mHardcodedCapabilities.Length();
-}
-
-void
-MediaEngineCameraVideoSource::GetCapability(size_t aIndex,
- webrtc::CaptureCapability& aOut) const
-{
- MOZ_ASSERT(aIndex < mHardcodedCapabilities.Length());
- aOut = mHardcodedCapabilities.SafeElementAt(aIndex, webrtc::CaptureCapability());
+ aOut.Clear();
+ for (auto& cap : mHardcodedCapabilities) {
+ aOut.AppendElement(CapabilityCandidate(cap));
+ }
}
uint32_t
MediaEngineCameraVideoSource::GetFitnessDistance(
const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId) const
{
@@ -104,30 +97,24 @@ MediaEngineCameraVideoSource::TrimLessFi
// Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
// A finite result may be used to calculate this device's ranking as a choice.
uint32_t
MediaEngineCameraVideoSource::GetBestFitnessDistance(
const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
const nsString& aDeviceId) const
{
- size_t num = NumCapabilities();
-
CapabilitySet candidateSet;
- for (size_t i = 0; i < num; i++) {
- candidateSet.AppendElement(i);
- }
-
+ GetCapabilityCandidateSet(candidateSet);
bool first = true;
for (const NormalizedConstraintSet* ns : aConstraintSets) {
for (size_t i = 0; i < candidateSet.Length(); ) {
auto& candidate = candidateSet[i];
- webrtc::CaptureCapability cap;
- GetCapability(candidate.mIndex, cap);
- uint32_t distance = GetFitnessDistance(cap, *ns, aDeviceId);
+ uint32_t distance = GetFitnessDistance(candidate.mCapability, *ns,
+ aDeviceId);
if (distance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
} else {
++i;
if (first) {
candidate.mDistance = distance;
}
}
@@ -229,52 +216,47 @@ MediaEngineCameraVideoSource::ChooseCapa
if (aConstraints.mAdvanced.size()) {
LOG(("Advanced array[%" PRIuSIZE "]:", aConstraints.mAdvanced.size()));
for (auto& advanced : aConstraints.mAdvanced) {
LogConstraints(advanced);
}
}
}
- size_t num = NumCapabilities();
-
CapabilitySet candidateSet;
- for (size_t i = 0; i < num; i++) {
- candidateSet.AppendElement(i);
- }
+ GetCapabilityCandidateSet(candidateSet);
+ size_t num = candidateSet.Length();
// First, filter capabilities by required constraints (min, max, exact).
for (size_t i = 0; i < candidateSet.Length();) {
auto& candidate = candidateSet[i];
- webrtc::CaptureCapability cap;
- GetCapability(candidate.mIndex, cap);
- candidate.mDistance = GetFitnessDistance(cap, aConstraints, aDeviceId);
- LogCapability("Capability", cap, candidate.mDistance);
+ candidate.mDistance = GetFitnessDistance(candidate.mCapability,
+ aConstraints, aDeviceId);
+ LogCapability("Capability", candidate.mCapability, candidate.mDistance);
if (candidate.mDistance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
} else {
++i;
}
}
if (!candidateSet.Length()) {
- LOG(("failed to find capability match from %" PRIuSIZE " choices",num));
+ LOG(("failed to find capability match from %" PRIuSIZE " choices", num));
return false;
}
// Filter further with all advanced constraints (that don't overconstrain).
for (const auto &cs : aConstraints.mAdvanced) {
CapabilitySet rejects;
for (size_t i = 0; i < candidateSet.Length();) {
auto& candidate = candidateSet[i];
- webrtc::CaptureCapability cap;
- GetCapability(candidate.mIndex, cap);
- if (GetFitnessDistance(cap, cs, aDeviceId) == UINT32_MAX) {
+ if (GetFitnessDistance(candidate.mCapability, cs, aDeviceId)
+ == UINT32_MAX) {
rejects.AppendElement(candidate);
candidateSet.RemoveElementAt(i);
} else {
++i;
}
}
if (!candidateSet.Length()) {
candidateSet.AppendElements(Move(rejects));
@@ -293,41 +275,38 @@ MediaEngineCameraVideoSource::ChooseCapa
{
MediaTrackConstraintSet prefs;
prefs.mWidth.SetAsLong() = aPrefs.GetWidth();
prefs.mHeight.SetAsLong() = aPrefs.GetHeight();
prefs.mFrameRate.SetAsDouble() = aPrefs.mFPS;
NormalizedConstraintSet normPrefs(prefs, false);
for (auto& candidate : candidateSet) {
- webrtc::CaptureCapability cap;
- GetCapability(candidate.mIndex, cap);
- candidate.mDistance = GetFitnessDistance(cap, normPrefs, aDeviceId);
+ candidate.mDistance = GetFitnessDistance(candidate.mCapability, normPrefs,
+ aDeviceId);
}
TrimLessFitCandidates(candidateSet);
}
// Any remaining multiples all have the same distance, but may vary on
// format. Some formats are more desirable for certain use like WebRTC.
// E.g. I420 over RGB24 can remove a needless format conversion.
bool found = false;
for (auto& candidate : candidateSet) {
- webrtc::CaptureCapability cap;
- GetCapability(candidate.mIndex, cap);
- if (cap.rawType == webrtc::RawVideoType::kVideoI420 ||
- cap.rawType == webrtc::RawVideoType::kVideoYUY2 ||
- cap.rawType == webrtc::RawVideoType::kVideoYV12) {
- mCapability = cap;
+ if (candidate.mCapability.rawType == webrtc::RawVideoType::kVideoI420 ||
+ candidate.mCapability.rawType == webrtc::RawVideoType::kVideoYUY2 ||
+ candidate.mCapability.rawType == webrtc::RawVideoType::kVideoYV12) {
+ mCapability = candidate.mCapability;
found = true;
break;
}
}
if (!found) {
- GetCapability(candidateSet[0].mIndex, mCapability);
+ mCapability = candidateSet[0].mCapability;
}
LogCapability("Chosen capability", mCapability, sameDistance);
return true;
}
void
MediaEngineCameraVideoSource::SetName(nsString aName)
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -59,20 +59,20 @@ public:
uint32_t GetBestFitnessDistance(
const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
const nsString& aDeviceId) const override;
void Shutdown() override {};
protected:
struct CapabilityCandidate {
- explicit CapabilityCandidate(uint8_t index, uint32_t distance = 0)
- : mIndex(index), mDistance(distance) {}
-
- size_t mIndex;
+ explicit CapabilityCandidate(const webrtc::CaptureCapability cap,
+ uint32_t distance = 0)
+ : mCapability(cap), mDistance(distance) {}
+ const webrtc::CaptureCapability mCapability;
uint32_t mDistance;
};
typedef nsTArray<CapabilityCandidate> CapabilitySet;
~MediaEngineCameraVideoSource() {}
// guts for appending data to the MSG track
virtual bool AppendToTrack(SourceMediaStream* aSource,
@@ -83,18 +83,17 @@ protected:
uint32_t GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
const NormalizedConstraintSet &aConstraints,
const nsString& aDeviceId) const;
static void TrimLessFitCandidates(CapabilitySet& set);
static void LogConstraints(const NormalizedConstraintSet& aConstraints);
static void LogCapability(const char* aHeader,
const webrtc::CaptureCapability &aCapability,
uint32_t aDistance);
- virtual size_t NumCapabilities() const;
- virtual void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) const;
+ virtual void GetCapabilityCandidateSet(CapabilitySet& aOut) const;
virtual bool ChooseCapability(const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId);
void SetName(nsString aName);
void SetUUID(const char* aUUID);
const nsCString& GetUUID() const; // protected access
// Engine variables.
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -435,34 +435,16 @@ MediaEngineRemoteVideoSource::DeliverFra
// We'll push the frame into the MSG on the next NotifyPull. This will avoid
// swamping the MSG with frames should it be taking longer than normal to run
// an iteration.
return 0;
}
-size_t
-MediaEngineRemoteVideoSource::NumCapabilities() const
-{
- mHardcodedCapabilities.Clear();
- int num = mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::NumberOfCapabilities,
- mCapEngine,
- GetUUID().get());
- if (num < 1) {
- // The default for devices that don't return discrete capabilities: treat
- // them as supporting all capabilities orthogonally. E.g. screensharing.
- // CaptureCapability defaults key values to 0, which means accept any value.
- mHardcodedCapabilities.AppendElement(webrtc::CaptureCapability());
- num = mHardcodedCapabilities.Length(); // 1
- }
- return num;
-}
-
bool
MediaEngineRemoteVideoSource::ChooseCapability(
const NormalizedConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId)
{
AssertIsOnOwningThread();
@@ -483,29 +465,40 @@ MediaEngineRemoteVideoSource::ChooseCapa
return true;
}
default:
return MediaEngineCameraVideoSource::ChooseCapability(aConstraints, aPrefs, aDeviceId);
}
}
-void
-MediaEngineRemoteVideoSource::GetCapability(size_t aIndex,
- webrtc::CaptureCapability& aOut) const
+void MediaEngineRemoteVideoSource::GetCapabilityCandidateSet(
+ CapabilitySet& aOut) const
{
- if (!mHardcodedCapabilities.IsEmpty()) {
- MediaEngineCameraVideoSource::GetCapability(aIndex, aOut);
+ aOut.Clear();
+ nsTArray<webrtc::CaptureCapability> caps;
+ mozilla::camera::GetChildAndCall(
+ &mozilla::camera::CamerasChild::GetCaptureCapabilities,
+ mCapEngine,
+ GetUUID().get(),
+ caps);
+ for (auto& cap : caps) {
+ aOut.AppendElement(CapabilityCandidate(cap));
+ }
+ if (aOut.IsEmpty()) {
+ if (mHardcodedCapabilities.IsEmpty()) {
+ // The default for devices that don't return discrete capabilities: treat
+ // them as supporting all capabilities orthogonally. E.g. screensharing.
+ // CaptureCapability defaults key values to 0, which means accept any
+ // value.
+ mHardcodedCapabilities.AppendElement(webrtc::CaptureCapability());
+ }
+ // Return the hardcoded set of capabilities (now of size 1)
+ MediaEngineCameraVideoSource::GetCapabilityCandidateSet(aOut);
}
- mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::GetCaptureCapability,
- mCapEngine,
- GetUUID().get(),
- aIndex,
- aOut);
}
void MediaEngineRemoteVideoSource::Refresh(int aIndex) {
// NOTE: mCaptureIndex might have changed when allocated!
// Use aIndex to update information, but don't change mCaptureIndex!!
// Caller looked up this source by uniqueId, so it shouldn't change
char deviceName[kMaxDeviceNameLength];
char uniqueId[kMaxUniqueIdLength];
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -95,18 +95,17 @@ public:
bool GetScary() const override { return mScary; }
protected:
~MediaEngineRemoteVideoSource() { }
private:
// Initialize the needed Video engine interfaces.
void Init();
- size_t NumCapabilities() const override;
- void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) const override;
+ virtual void GetCapabilityCandidateSet(CapabilitySet& aOut) const override;
void SetLastCapability(const webrtc::CaptureCapability& aCapability);
nsresult
UpdateSingleSource(const AllocationHandle* aHandle,
const NormalizedConstraints& aNetConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
const char** aOutBadConstraint) override;
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -209,33 +209,26 @@ MediaEngineWebRTC::EnumerateVideoDevices
sizeof(uniqueId),
&scarySource);
if (error) {
LOG(("camera:GetCaptureDevice: Failed %d", error ));
continue;
}
#ifdef DEBUG
LOG((" Capture Device Index %d, Name %s", i, deviceName));
-
- webrtc::CaptureCapability cap;
- int numCaps = mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::NumberOfCapabilities,
- capEngine,
- uniqueId);
- LOG(("Number of Capabilities %d", numCaps));
- for (int j = 0; j < numCaps; j++) {
- if (mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::GetCaptureCapability,
- capEngine,
- uniqueId,
- j, cap) != 0) {
- break;
+ nsTArray<webrtc::CaptureCapability> capList;
+ if (!mozilla::camera::GetChildAndCall(
+ &mozilla::camera::CamerasChild::GetCaptureCapabilities,
+ capEngine, uniqueId, capList))
+ {
+ LOG(("Number of Capabilities %" PRIuSIZE, capList.Length()));
+ for (auto& cap : capList) {
+ LOG(("type=%d width=%d height=%d maxFPS=%d",
+ cap.rawType, cap.width, cap.height, cap.maxFPS));
}
- LOG(("type=%d width=%d height=%d maxFPS=%d",
- cap.rawType, cap.width, cap.height, cap.maxFPS ));
}
#endif
if (uniqueId[0] == '\0') {
// In case a device doesn't set uniqueId!
strncpy(uniqueId, deviceName, sizeof(uniqueId));
uniqueId[sizeof(uniqueId)-1] = '\0'; // strncpy isn't safe
}