mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-23 00:47:31 +09:00
[WebRTC] updated to upstream branch 49 and related.
this patch is based on 38d7a7883...226f2f0bd
This commit is contained in:
parent
e79847e7b9
commit
a3239eaa4d
2838 changed files with 151221 additions and 159688 deletions
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "CamerasChild.h"
|
||||
|
||||
#include "webrtc/video_engine/include/vie_capture.h"
|
||||
#undef FF
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
|
@ -336,7 +335,7 @@ int
|
|||
CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int capability_number,
|
||||
webrtc::CaptureCapability& capability)
|
||||
webrtc::VideoCaptureCapability& capability)
|
||||
{
|
||||
LOG(("GetCaptureCapability: %s %d", unique_idUTF8, capability_number));
|
||||
RefPtr<CamerasChild> deathGrip = this;
|
||||
|
|
@ -352,7 +351,7 @@ CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasChild::RecvReplyGetCaptureCapability(const CaptureCapability& ipcCapability)
|
||||
CamerasChild::RecvReplyGetCaptureCapability(const VideoCaptureCapability& ipcCapability)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
MonitorAutoLock monitor(mReplyMonitor);
|
||||
|
|
@ -414,7 +413,7 @@ int
|
|||
CamerasChild::AllocateCaptureDevice(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int unique_idUTF8Length,
|
||||
int& capture_id,
|
||||
int& aStreamId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
|
@ -427,7 +426,7 @@ CamerasChild::AllocateCaptureDevice(CaptureEngine aCapEngine,
|
|||
LockAndDispatch<> dispatcher(this, __func__, runnable);
|
||||
if (dispatcher.Success()) {
|
||||
LOG(("Capture Device allocated: %d", mReplyInteger));
|
||||
capture_id = mReplyInteger;
|
||||
aStreamId = mReplyInteger;
|
||||
}
|
||||
return dispatcher.ReturnValue();
|
||||
}
|
||||
|
|
@ -460,7 +459,7 @@ CamerasChild::ReleaseCaptureDevice(CaptureEngine aCapEngine,
|
|||
|
||||
void
|
||||
CamerasChild::AddCallback(const CaptureEngine aCapEngine, const int capture_id,
|
||||
webrtc::ExternalRenderer* render)
|
||||
FrameRelay* render)
|
||||
{
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
CapturerElement ce;
|
||||
|
|
@ -486,12 +485,12 @@ CamerasChild::RemoveCallback(const CaptureEngine aCapEngine, const int capture_i
|
|||
int
|
||||
CamerasChild::StartCapture(CaptureEngine aCapEngine,
|
||||
const int capture_id,
|
||||
webrtc::CaptureCapability& webrtcCaps,
|
||||
webrtc::ExternalRenderer* cb)
|
||||
webrtc::VideoCaptureCapability& webrtcCaps,
|
||||
FrameRelay* cb)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
AddCallback(aCapEngine, capture_id, cb);
|
||||
CaptureCapability capCap(webrtcCaps.width,
|
||||
VideoCaptureCapability capCap(webrtcCaps.width,
|
||||
webrtcCaps.height,
|
||||
webrtcCaps.maxFPS,
|
||||
webrtcCaps.expectedCaptureDelay,
|
||||
|
|
@ -500,7 +499,7 @@ CamerasChild::StartCapture(CaptureEngine aCapEngine,
|
|||
webrtcCaps.interlaced);
|
||||
RefPtr<CamerasChild> deathGrip = this;
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
mozilla::NewNonOwningRunnableMethod<CaptureEngine, int, CaptureCapability>
|
||||
mozilla::NewNonOwningRunnableMethod<CaptureEngine, int, VideoCaptureCapability>
|
||||
(this, &CamerasChild::SendStartCapture, aCapEngine, capture_id, capCap);
|
||||
LockAndDispatch<> dispatcher(this, __func__, runnable);
|
||||
return dispatcher.ReturnValue();
|
||||
|
|
@ -617,18 +616,12 @@ bool
|
|||
CamerasChild::RecvDeliverFrame(const CaptureEngine& capEngine,
|
||||
const int& capId,
|
||||
mozilla::ipc::Shmem&& shmem,
|
||||
const size_t& size,
|
||||
const uint32_t& time_stamp,
|
||||
const int64_t& ntp_time,
|
||||
const int64_t& render_time)
|
||||
const VideoFrameProperties & prop)
|
||||
{
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
if (Callback(capEngine, capId)) {
|
||||
unsigned char* image = shmem.get<unsigned char>();
|
||||
Callback(capEngine, capId)->DeliverFrame(image, size,
|
||||
time_stamp,
|
||||
ntp_time, render_time,
|
||||
nullptr);
|
||||
Callback(capEngine, capId)->DeliverFrame(image, prop);
|
||||
} else {
|
||||
LOG(("DeliverFrame called with dead callback"));
|
||||
}
|
||||
|
|
@ -673,7 +666,7 @@ CamerasChild::RecvFrameSizeChange(const CaptureEngine& capEngine,
|
|||
LOG((__PRETTY_FUNCTION__));
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
if (Callback(capEngine, capId)) {
|
||||
Callback(capEngine, capId)->FrameSizeChange(w, h, 0);
|
||||
Callback(capEngine, capId)->FrameSizeChange(w, h);
|
||||
} else {
|
||||
LOG(("Frame size change with dead callback"));
|
||||
}
|
||||
|
|
@ -717,7 +710,7 @@ CamerasChild::~CamerasChild()
|
|||
MOZ_COUNT_DTOR(CamerasChild);
|
||||
}
|
||||
|
||||
webrtc::ExternalRenderer* CamerasChild::Callback(CaptureEngine aCapEngine,
|
||||
FrameRelay* CamerasChild::Callback(CaptureEngine aCapEngine,
|
||||
int capture_id)
|
||||
{
|
||||
for (unsigned int i = 0; i < mCallbacks.Length(); i++) {
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
// 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 "webrtc/video_renderer.h"
|
||||
#include "webrtc/modules/video_capture/video_capture_defines.h"
|
||||
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
@ -32,10 +32,17 @@ class BackgroundChildImpl;
|
|||
|
||||
namespace camera {
|
||||
|
||||
class FrameRelay {
|
||||
public:
|
||||
virtual int DeliverFrame(uint8_t* buffer,
|
||||
const mozilla::camera::VideoFrameProperties& props) = 0;
|
||||
virtual void FrameSizeChange(unsigned int w, unsigned int h) = 0;
|
||||
};
|
||||
|
||||
struct CapturerElement {
|
||||
CaptureEngine engine;
|
||||
int id;
|
||||
webrtc::ExternalRenderer* callback;
|
||||
FrameRelay* callback;
|
||||
};
|
||||
|
||||
// Forward declaration so we can work with pointers to it.
|
||||
|
|
@ -157,9 +164,9 @@ public:
|
|||
|
||||
// IPC messages recevied, received on the PBackground thread
|
||||
// these are the actual callbacks with data
|
||||
virtual bool RecvDeliverFrame(const CaptureEngine&, const int&, mozilla::ipc::Shmem&&,
|
||||
const size_t&, const uint32_t&, const int64_t&,
|
||||
const int64_t&) override;
|
||||
virtual bool RecvDeliverFrame(const CaptureEngine&, const int&,
|
||||
mozilla::ipc::Shmem&&,
|
||||
const VideoFrameProperties & prop) override;
|
||||
virtual bool RecvFrameSizeChange(const CaptureEngine&, const int&,
|
||||
const int& w, const int& h) override;
|
||||
|
||||
|
|
@ -171,7 +178,7 @@ public:
|
|||
virtual bool RecvReplyNumberOfCaptureDevices(const int&) override;
|
||||
virtual bool RecvReplyNumberOfCapabilities(const int&) override;
|
||||
virtual bool RecvReplyAllocateCaptureDevice(const int&) override;
|
||||
virtual bool RecvReplyGetCaptureCapability(const CaptureCapability& capability) override;
|
||||
virtual bool RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
|
||||
virtual bool RecvReplyGetCaptureDevice(const nsCString& device_name,
|
||||
const nsCString& device_id,
|
||||
const bool& scary) override;
|
||||
|
|
@ -188,8 +195,8 @@ public:
|
|||
int ReleaseCaptureDevice(CaptureEngine aCapEngine,
|
||||
const int capture_id);
|
||||
int StartCapture(CaptureEngine aCapEngine,
|
||||
const int capture_id, webrtc::CaptureCapability& capability,
|
||||
webrtc::ExternalRenderer* func);
|
||||
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,
|
||||
|
|
@ -199,7 +206,7 @@ public:
|
|||
int GetCaptureCapability(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int capability_number,
|
||||
webrtc::CaptureCapability& capability);
|
||||
webrtc::VideoCaptureCapability& capability);
|
||||
int GetCaptureDevice(CaptureEngine aCapEngine,
|
||||
unsigned int list_number, char* device_nameUTF8,
|
||||
const unsigned int device_nameUTF8Length,
|
||||
|
|
@ -209,7 +216,7 @@ public:
|
|||
void ShutdownAll();
|
||||
int EnsureInitialized(CaptureEngine aCapEngine);
|
||||
|
||||
webrtc::ExternalRenderer* Callback(CaptureEngine aCapEngine, int capture_id);
|
||||
FrameRelay* Callback(CaptureEngine aCapEngine, int capture_id);
|
||||
|
||||
private:
|
||||
CamerasChild();
|
||||
|
|
@ -219,7 +226,7 @@ private:
|
|||
bool DispatchToParent(nsIRunnable* aRunnable,
|
||||
MonitorAutoLock& aMonitor);
|
||||
void AddCallback(const CaptureEngine aCapEngine, const int capture_id,
|
||||
webrtc::ExternalRenderer* render);
|
||||
FrameRelay* render);
|
||||
void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id);
|
||||
void ShutdownParent();
|
||||
void ShutdownChild();
|
||||
|
|
@ -246,7 +253,7 @@ private:
|
|||
// Async responses data contents;
|
||||
bool mReplySuccess;
|
||||
int mReplyInteger;
|
||||
webrtc::CaptureCapability mReplyCapability;
|
||||
webrtc::VideoCaptureCapability mReplyCapability;
|
||||
nsCString mReplyDeviceName;
|
||||
nsCString mReplyDeviceID;
|
||||
bool mReplyScary;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "CamerasParent.h"
|
||||
#include "MediaEngine.h"
|
||||
#include "MediaUtils.h"
|
||||
#include "VideoFrameUtils.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
|
@ -26,9 +27,11 @@
|
|||
#endif
|
||||
|
||||
#undef LOG
|
||||
#undef LOG_VERBOSE
|
||||
#undef LOG_ENABLED
|
||||
mozilla::LazyLogModule gCamerasParentLog("CamerasParent");
|
||||
#define LOG(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Debug, args)
|
||||
#define LOG_VERBOSE(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Verbose, args)
|
||||
#define LOG_ENABLED() MOZ_LOG_TEST(gCamerasParentLog, mozilla::LogLevel::Debug)
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -44,7 +47,7 @@ namespace camera {
|
|||
// suitable for UI access.
|
||||
|
||||
// InputObserver is owned by CamerasParent, and it has a ref to CamerasParent
|
||||
void InputObserver::DeviceChange() {
|
||||
void InputObserver::OnDeviceChange() {
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
MOZ_ASSERT(mParent);
|
||||
|
||||
|
|
@ -63,80 +66,30 @@ void InputObserver::DeviceChange() {
|
|||
thread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
};
|
||||
|
||||
class FrameSizeChangeRunnable : public Runnable {
|
||||
class DeliverFrameRunnable : public ::mozilla::Runnable {
|
||||
public:
|
||||
FrameSizeChangeRunnable(CamerasParent *aParent, CaptureEngine capEngine,
|
||||
int cap_id, unsigned int aWidth, unsigned int aHeight)
|
||||
: mParent(aParent), mCapEngine(capEngine), mCapId(cap_id),
|
||||
mWidth(aWidth), mHeight(aHeight) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
if (mParent->IsShuttingDown()) {
|
||||
// Communication channel is being torn down
|
||||
LOG(("FrameSizeChangeRunnable is active without active Child"));
|
||||
mResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mParent->SendFrameSizeChange(mCapEngine, mCapId, mWidth, mHeight)) {
|
||||
mResult = -1;
|
||||
} else {
|
||||
mResult = 0;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int GetResult() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<CamerasParent> mParent;
|
||||
CaptureEngine mCapEngine;
|
||||
int mCapId;
|
||||
unsigned int mWidth;
|
||||
unsigned int mHeight;
|
||||
int mResult;
|
||||
};
|
||||
|
||||
int
|
||||
CallbackHelper::FrameSizeChange(unsigned int w, unsigned int h,
|
||||
unsigned int streams)
|
||||
{
|
||||
LOG(("CallbackHelper Video FrameSizeChange: %ux%u", w, h));
|
||||
RefPtr<FrameSizeChangeRunnable> runnable =
|
||||
new FrameSizeChangeRunnable(mParent, mCapEngine, mCapturerId, w, h);
|
||||
MOZ_ASSERT(mParent);
|
||||
nsIThread * thread = mParent->GetBackgroundThread();
|
||||
MOZ_ASSERT(thread != nullptr);
|
||||
thread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
class DeliverFrameRunnable : public Runnable {
|
||||
public:
|
||||
DeliverFrameRunnable(CamerasParent *aParent,
|
||||
CaptureEngine engine,
|
||||
int cap_id,
|
||||
ShmemBuffer buffer,
|
||||
unsigned char* altbuffer,
|
||||
size_t size,
|
||||
uint32_t time_stamp,
|
||||
int64_t ntp_time,
|
||||
int64_t render_time)
|
||||
: mParent(aParent), mCapEngine(engine), mCapId(cap_id), mBuffer(Move(buffer)),
|
||||
mSize(size), mTimeStamp(time_stamp), mNtpTime(ntp_time),
|
||||
mRenderTime(render_time) {
|
||||
DeliverFrameRunnable(CamerasParent *aParent, CaptureEngine aEngine,
|
||||
uint32_t aStreamId, const webrtc::VideoFrame& aFrame,
|
||||
const VideoFrameProperties& aProperties)
|
||||
: mParent(aParent), mCapEngine(aEngine), mStreamId(aStreamId),
|
||||
mProperties(aProperties)
|
||||
{
|
||||
// No ShmemBuffer (of the right size) was available, so make an
|
||||
// extra buffer here. We have no idea when we are going to run and
|
||||
// it will be potentially long after the webrtc frame callback has
|
||||
// returned, so the copy needs to be no later than here.
|
||||
// We will need to copy this back into a Shmem later on so we prefer
|
||||
// using ShmemBuffers to avoid the extra copy.
|
||||
if (altbuffer != nullptr) {
|
||||
mAlternateBuffer.reset(new unsigned char[size]);
|
||||
memcpy(mAlternateBuffer.get(), altbuffer, size);
|
||||
}
|
||||
};
|
||||
mAlternateBuffer.reset(new unsigned char[aProperties.bufferSize()]);
|
||||
VideoFrameUtils::CopyVideoFrameBuffers(mAlternateBuffer.get(),
|
||||
aProperties.bufferSize(), aFrame);
|
||||
}
|
||||
|
||||
DeliverFrameRunnable(CamerasParent* aParent, CaptureEngine aEngine,
|
||||
uint32_t aStreamId, ShmemBuffer aBuffer, VideoFrameProperties& aProperties)
|
||||
: mParent(aParent), mCapEngine(aEngine), mStreamId(aStreamId),
|
||||
mBuffer(Move(aBuffer)), mProperties(aProperties)
|
||||
{};
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
if (mParent->IsShuttingDown()) {
|
||||
|
|
@ -144,10 +97,8 @@ public:
|
|||
mResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mParent->DeliverFrameOverIPC(mCapEngine, mCapId,
|
||||
Move(mBuffer), mAlternateBuffer.get(),
|
||||
mSize, mTimeStamp,
|
||||
mNtpTime, mRenderTime)) {
|
||||
if (!mParent->DeliverFrameOverIPC(mCapEngine, mStreamId, Move(mBuffer),
|
||||
mAlternateBuffer.get(), mProperties)) {
|
||||
mResult = -1;
|
||||
} else {
|
||||
mResult = 0;
|
||||
|
|
@ -162,13 +113,10 @@ public:
|
|||
private:
|
||||
RefPtr<CamerasParent> mParent;
|
||||
CaptureEngine mCapEngine;
|
||||
int mCapId;
|
||||
uint32_t mStreamId;
|
||||
ShmemBuffer mBuffer;
|
||||
mozilla::UniquePtr<unsigned char[]> mAlternateBuffer;
|
||||
size_t mSize;
|
||||
uint32_t mTimeStamp;
|
||||
int64_t mNtpTime;
|
||||
int64_t mRenderTime;
|
||||
VideoFrameProperties mProperties;
|
||||
int mResult;
|
||||
};
|
||||
|
||||
|
|
@ -258,14 +206,11 @@ CamerasParent::StopVideoCapture()
|
|||
}
|
||||
|
||||
int
|
||||
CamerasParent::DeliverFrameOverIPC(CaptureEngine cap_engine,
|
||||
int cap_id,
|
||||
ShmemBuffer buffer,
|
||||
unsigned char* altbuffer,
|
||||
size_t size,
|
||||
uint32_t time_stamp,
|
||||
int64_t ntp_time,
|
||||
int64_t render_time)
|
||||
CamerasParent::DeliverFrameOverIPC(CaptureEngine capEng,
|
||||
uint32_t aStreamId,
|
||||
ShmemBuffer buffer,
|
||||
unsigned char* altbuffer,
|
||||
VideoFrameProperties& aProps)
|
||||
{
|
||||
// No ShmemBuffers were available, so construct one now of the right size
|
||||
// and copy into it. That is an extra copy, but we expect this to be
|
||||
|
|
@ -273,7 +218,7 @@ CamerasParent::DeliverFrameOverIPC(CaptureEngine cap_engine,
|
|||
// buffer of the right size.
|
||||
if (altbuffer != nullptr) {
|
||||
// Get a shared memory buffer from the pool, at least size big
|
||||
ShmemBuffer shMemBuff = mShmemPool.Get(this, size);
|
||||
ShmemBuffer shMemBuff = mShmemPool.Get(this, aProps.bufferSize());
|
||||
|
||||
if (!shMemBuff.Valid()) {
|
||||
LOG(("No usable Video shmem in DeliverFrame (out of buffers?)"));
|
||||
|
|
@ -282,20 +227,18 @@ CamerasParent::DeliverFrameOverIPC(CaptureEngine cap_engine,
|
|||
}
|
||||
|
||||
// get() and Size() check for proper alignment of the segment
|
||||
memcpy(shMemBuff.GetBytes(), altbuffer, size);
|
||||
memcpy(shMemBuff.GetBytes(), altbuffer, aProps.bufferSize());
|
||||
|
||||
if (!SendDeliverFrame(cap_engine, cap_id,
|
||||
shMemBuff.Get(), size,
|
||||
time_stamp, ntp_time, render_time)) {
|
||||
if (!SendDeliverFrame(capEng, aStreamId,
|
||||
shMemBuff.Get(), aProps)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(buffer.Valid());
|
||||
// ShmemBuffer was available, we're all good. A single copy happened
|
||||
// in the original webrtc callback.
|
||||
if (!SendDeliverFrame(cap_engine, cap_id,
|
||||
buffer.Get(), size,
|
||||
time_stamp, ntp_time, render_time)) {
|
||||
if (!SendDeliverFrame(capEng, aStreamId,
|
||||
buffer.Get(), aProps)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -309,16 +252,16 @@ CamerasParent::GetBuffer(size_t aSize)
|
|||
return mShmemPool.GetIfAvailable(aSize);
|
||||
}
|
||||
|
||||
int
|
||||
CallbackHelper::DeliverFrame(unsigned char* buffer,
|
||||
size_t size,
|
||||
uint32_t time_stamp,
|
||||
int64_t ntp_time,
|
||||
int64_t render_time,
|
||||
void *handle)
|
||||
int32_t
|
||||
CallbackHelper::RenderFrame(uint32_t aStreamId, const webrtc::VideoFrame& aVideoFrame)
|
||||
{
|
||||
LOG_VERBOSE((__PRETTY_FUNCTION__));
|
||||
RefPtr<DeliverFrameRunnable> runnable = nullptr;
|
||||
// Get frame properties
|
||||
camera::VideoFrameProperties properties;
|
||||
VideoFrameUtils::InitFrameBufferProperties(aVideoFrame, properties);
|
||||
// Get a shared memory buffer to copy the frame data into
|
||||
ShmemBuffer shMemBuffer = mParent->GetBuffer(size);
|
||||
ShmemBuffer shMemBuffer = mParent->GetBuffer(properties.bufferSize());
|
||||
if (!shMemBuffer.Valid()) {
|
||||
// Either we ran out of buffers or they're not the right size yet
|
||||
LOG(("Correctly sized Video shmem not available in DeliverFrame"));
|
||||
|
|
@ -326,30 +269,33 @@ CallbackHelper::DeliverFrame(unsigned char* buffer,
|
|||
// the DeliverFrameRunnable constructor.
|
||||
} else {
|
||||
// Shared memory buffers of the right size are available, do the copy here.
|
||||
memcpy(shMemBuffer.GetBytes(), buffer, size);
|
||||
// Mark the original buffer as cleared.
|
||||
buffer = nullptr;
|
||||
VideoFrameUtils::CopyVideoFrameBuffers(shMemBuffer.GetBytes(),
|
||||
properties.bufferSize(), aVideoFrame);
|
||||
runnable = new DeliverFrameRunnable(mParent, mCapEngine, mStreamId,
|
||||
Move(shMemBuffer), properties);
|
||||
}
|
||||
if (!runnable.get()) {
|
||||
runnable = new DeliverFrameRunnable(mParent, mCapEngine, mStreamId,
|
||||
aVideoFrame, properties);
|
||||
}
|
||||
RefPtr<DeliverFrameRunnable> runnable =
|
||||
new DeliverFrameRunnable(mParent, mCapEngine, mCapturerId,
|
||||
Move(shMemBuffer), buffer, size, time_stamp,
|
||||
ntp_time, render_time);
|
||||
MOZ_ASSERT(mParent);
|
||||
nsIThread* thread = mParent->GetBackgroundThread();
|
||||
MOZ_ASSERT(thread != nullptr);
|
||||
thread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
return 0;
|
||||
}
|
||||
// XXX!!! FIX THIS -- we should move to pure DeliverI420Frame
|
||||
int
|
||||
CallbackHelper::DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame)
|
||||
|
||||
void
|
||||
CallbackHelper::OnIncomingCapturedFrame(const int32_t id, const webrtc::VideoFrame& aVideoFrame)
|
||||
{
|
||||
return DeliverFrame(const_cast<uint8_t*>(webrtc_frame.buffer(webrtc::kYPlane)),
|
||||
CalcBufferSize(webrtc::kI420, webrtc_frame.width(), webrtc_frame.height()),
|
||||
webrtc_frame.timestamp(),
|
||||
webrtc_frame.ntp_time_ms(),
|
||||
webrtc_frame.render_time_ms(),
|
||||
(void*) webrtc_frame.native_handle());
|
||||
LOG_VERBOSE((__PRETTY_FUNCTION__));
|
||||
RenderFrame(id,aVideoFrame);
|
||||
}
|
||||
|
||||
void
|
||||
CallbackHelper::OnCaptureDelayChanged(const int32_t id, const int32_t delay)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -361,15 +307,17 @@ CamerasParent::RecvReleaseFrame(mozilla::ipc::Shmem&& s) {
|
|||
bool
|
||||
CamerasParent::SetupEngine(CaptureEngine aCapEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
MOZ_ASSERT(mVideoCaptureThread->thread_id() == PlatformThread::CurrentId());
|
||||
EngineHelper *helper = &mEngines[aCapEngine];
|
||||
RefPtr<mozilla::camera::VideoEngine>* engine = &mEngines[aCapEngine];
|
||||
|
||||
// Already initialized
|
||||
if (helper->mEngine) {
|
||||
if (engine->get()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
webrtc::CaptureDeviceInfo *captureDeviceInfo = nullptr;
|
||||
UniquePtr<webrtc::Config> config(new webrtc::Config);
|
||||
|
||||
switch (aCapEngine) {
|
||||
case ScreenEngine:
|
||||
|
|
@ -398,43 +346,19 @@ CamerasParent::SetupEngine(CaptureEngine aCapEngine)
|
|||
break;
|
||||
}
|
||||
|
||||
helper->mConfig.Set<webrtc::CaptureDeviceInfo>(captureDeviceInfo);
|
||||
helper->mEngine = webrtc::VideoEngine::Create(helper->mConfig);
|
||||
config->Set<webrtc::CaptureDeviceInfo>(captureDeviceInfo);
|
||||
*engine = mozilla::camera::VideoEngine::Create(UniquePtr<const webrtc::Config>(config.release()));
|
||||
|
||||
if (!helper->mEngine) {
|
||||
if (!engine->get()) {
|
||||
LOG(("VideoEngine::Create failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
helper->mPtrViEBase = webrtc::ViEBase::GetInterface(helper->mEngine);
|
||||
if (!helper->mPtrViEBase) {
|
||||
LOG(("ViEBase::GetInterface failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (helper->mPtrViEBase->Init() < 0) {
|
||||
LOG(("ViEBase::Init failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
helper->mPtrViECapture = webrtc::ViECapture::GetInterface(helper->mEngine);
|
||||
if (!helper->mPtrViECapture) {
|
||||
LOG(("ViECapture::GetInterface failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<InputObserver>* observer = mObservers.AppendElement(new InputObserver(this));
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(0 == helper->mPtrViECapture->RegisterInputObserver(observer->get()));
|
||||
#else
|
||||
helper->mPtrViECapture->RegisterInputObserver(observer->get());
|
||||
#endif
|
||||
|
||||
helper->mPtrViERender = webrtc::ViERender::GetInterface(helper->mEngine);
|
||||
if (!helper->mPtrViERender) {
|
||||
LOG(("ViERender::GetInterface failed"));
|
||||
return false;
|
||||
auto device_info = engine->get()->GetOrCreateVideoCaptureDeviceInfo();
|
||||
MOZ_ASSERT(device_info);
|
||||
if (device_info) {
|
||||
device_info->RegisterVideoInputFeedBack(**observer);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -452,38 +376,25 @@ CamerasParent::CloseEngines()
|
|||
// Stop the callers
|
||||
while (mCallbacks.Length()) {
|
||||
auto capEngine = mCallbacks[0]->mCapEngine;
|
||||
auto capNum = mCallbacks[0]->mCapturerId;
|
||||
LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, capNum));
|
||||
StopCapture(capEngine, capNum);
|
||||
Unused << ReleaseCaptureDevice(capEngine, capNum);
|
||||
auto streamNum = mCallbacks[0]->mStreamId;
|
||||
LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, streamNum));
|
||||
StopCapture(capEngine, streamNum);
|
||||
Unused << ReleaseCaptureDevice(capEngine, streamNum);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngineIsRunning) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
if (mEngines[i].mPtrViERender) {
|
||||
mEngines[i].mPtrViERender->Release();
|
||||
mEngines[i].mPtrViERender = nullptr;
|
||||
}
|
||||
if (mEngines[i].mPtrViECapture) {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(0 == mEngines[i].mPtrViECapture->DeregisterInputObserver());
|
||||
#else
|
||||
mEngines[i].mPtrViECapture->DeregisterInputObserver();
|
||||
#endif
|
||||
if (auto engine = mEngines[i].get() ){
|
||||
if (engine->IsRunning()) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
|
||||
mEngines[i].mPtrViECapture->Release();
|
||||
mEngines[i].mPtrViECapture = nullptr;
|
||||
}
|
||||
if(mEngines[i].mPtrViEBase) {
|
||||
mEngines[i].mPtrViEBase->Release();
|
||||
mEngines[i].mPtrViEBase = nullptr;
|
||||
}
|
||||
if (mEngines[i].mEngine) {
|
||||
mEngines[i].mEngine->SetTraceCallback(nullptr);
|
||||
webrtc::VideoEngine::Delete(mEngines[i].mEngine);
|
||||
mEngines[i].mEngine = nullptr;
|
||||
auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo();
|
||||
MOZ_ASSERT(device_info);
|
||||
if (device_info) {
|
||||
device_info->DeRegisterVideoInputFeedBack();
|
||||
}
|
||||
mozilla::camera::VideoEngine::Delete(engine);
|
||||
mEngines[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,21 +403,21 @@ CamerasParent::CloseEngines()
|
|||
mWebRTCAlive = false;
|
||||
}
|
||||
|
||||
bool
|
||||
VideoEngine *
|
||||
CamerasParent::EnsureInitialized(int aEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
LOG_VERBOSE((__PRETTY_FUNCTION__));
|
||||
// We're shutting down, don't try to do new WebRTC ops.
|
||||
if (!mWebRTCAlive) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
CaptureEngine capEngine = static_cast<CaptureEngine>(aEngine);
|
||||
if (!SetupEngine(capEngine)) {
|
||||
LOG(("CamerasParent failed to initialize engine"));
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
return mEngines[aEngine];
|
||||
}
|
||||
|
||||
// Dispatch the runnable to do the camera operation on the
|
||||
|
|
@ -518,13 +429,15 @@ bool
|
|||
CamerasParent::RecvNumberOfCaptureDevices(const CaptureEngine& aCapEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
||||
LOG(("CaptureEngine=%d", aCapEngine));
|
||||
RefPtr<CamerasParent> self(this);
|
||||
RefPtr<Runnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine]() -> nsresult {
|
||||
int num = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
num = self->mEngines[aCapEngine].mPtrViECapture->NumberOfCaptureDevices();
|
||||
if (auto engine = self->EnsureInitialized(aCapEngine)) {
|
||||
if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
|
||||
num = devInfo->NumberOfDevices();
|
||||
}
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, num]() -> nsresult {
|
||||
|
|
@ -591,11 +504,10 @@ CamerasParent::RecvNumberOfCapabilities(const CaptureEngine& aCapEngine,
|
|||
RefPtr<Runnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine]() -> nsresult {
|
||||
int num = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
num =
|
||||
self->mEngines[aCapEngine].mPtrViECapture->NumberOfCapabilities(
|
||||
unique_id.get(),
|
||||
MediaEngineSource::kMaxUniqueIdLength);
|
||||
if (auto engine = self->EnsureInitialized(aCapEngine)) {
|
||||
if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
|
||||
num = devInfo->NumberOfCapabilities(unique_id.get());
|
||||
}
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, num]() -> nsresult {
|
||||
|
|
@ -630,18 +542,19 @@ CamerasParent::RecvGetCaptureCapability(const CaptureEngine& aCapEngine,
|
|||
RefPtr<CamerasParent> self(this);
|
||||
RefPtr<Runnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine, num]() -> nsresult {
|
||||
webrtc::CaptureCapability webrtcCaps;
|
||||
webrtc::VideoCaptureCapability webrtcCaps;
|
||||
int error = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureCapability(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, num, webrtcCaps);
|
||||
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;
|
||||
}
|
||||
CaptureCapability capCap(webrtcCaps.width,
|
||||
VideoCaptureCapability capCap(webrtcCaps.width,
|
||||
webrtcCaps.height,
|
||||
webrtcCaps.maxFPS,
|
||||
webrtcCaps.expectedCaptureDelay,
|
||||
|
|
@ -682,15 +595,15 @@ CamerasParent::RecvGetCaptureDevice(const CaptureEngine& aCapEngine,
|
|||
char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
|
||||
nsCString name;
|
||||
nsCString uniqueId;
|
||||
int devicePid = 0;
|
||||
pid_t devicePid = 0;
|
||||
int error = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureDevice(aListNumber,
|
||||
deviceName,
|
||||
sizeof(deviceName),
|
||||
deviceUniqueId,
|
||||
sizeof(deviceUniqueId),
|
||||
&devicePid);
|
||||
if (auto engine = self->EnsureInitialized(aCapEngine)) {
|
||||
if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
|
||||
error = devInfo->GetDeviceName(aListNumber, deviceName, sizeof(deviceName),
|
||||
deviceUniqueId, sizeof(deviceUniqueId),
|
||||
nullptr, 0,
|
||||
&devicePid);
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
name.Assign(deviceName);
|
||||
|
|
@ -806,8 +719,17 @@ CamerasParent::RecvAllocateCaptureDevice(const CaptureEngine& aCapEngine,
|
|||
int numdev = -1;
|
||||
int error = -1;
|
||||
if (allowed && self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
|
||||
auto engine = self->mEngines[aCapEngine].get();
|
||||
engine->CreateVideoCapture(numdev, unique_id.get());
|
||||
engine->WithEntry(numdev, [&error](VideoEngine::CaptureEntry& cap) {
|
||||
if (cap.VideoCapture()) {
|
||||
if (!cap.VideoRenderer()) {
|
||||
LOG(("VideoEngine::VideoRenderer() failed"));
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, numdev, error]() -> nsresult {
|
||||
|
|
@ -838,8 +760,8 @@ CamerasParent::ReleaseCaptureDevice(const CaptureEngine& aCapEngine,
|
|||
const int& capnum)
|
||||
{
|
||||
int error = -1;
|
||||
if (EnsureInitialized(aCapEngine)) {
|
||||
error = mEngines[aCapEngine].mPtrViECapture->ReleaseCaptureDevice(capnum);
|
||||
if (auto engine = EnsureInitialized(aCapEngine)) {
|
||||
error = engine->ReleaseVideoCapture(capnum);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
@ -881,44 +803,48 @@ CamerasParent::RecvReleaseCaptureDevice(const CaptureEngine& aCapEngine,
|
|||
bool
|
||||
CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
|
||||
const int& capnum,
|
||||
const CaptureCapability& ipcCaps)
|
||||
const VideoCaptureCapability& ipcCaps)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
||||
RefPtr<CamerasParent> self(this);
|
||||
RefPtr<Runnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, capnum, ipcCaps]() -> nsresult {
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
CallbackHelper** cbh;
|
||||
webrtc::ExternalRenderer* render;
|
||||
EngineHelper* helper = nullptr;
|
||||
webrtc::VideoRenderCallback* render;
|
||||
VideoEngine* engine = nullptr;
|
||||
int error = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
cbh = self->mCallbacks.AppendElement(
|
||||
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
|
||||
render = static_cast<webrtc::ExternalRenderer*>(*cbh);
|
||||
render = static_cast<webrtc::VideoRenderCallback*>(*cbh);
|
||||
|
||||
helper = &self->mEngines[aCapEngine];
|
||||
error =
|
||||
helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
|
||||
if (!error) {
|
||||
error = helper->mPtrViERender->StartRender(capnum);
|
||||
}
|
||||
engine = self->mEngines[aCapEngine];
|
||||
engine->WithEntry(capnum, [capnum, &render, &engine, &error, &ipcCaps, &cbh](VideoEngine::CaptureEntry& cap) {
|
||||
cap.VideoRenderer()->AddIncomingRenderStream(capnum,0, 0., 0., 1., 1.);
|
||||
error = cap.VideoRenderer()->AddExternalRenderCallback(capnum, render);
|
||||
if (!error) {
|
||||
error = cap.VideoRenderer()->StartRender(capnum);
|
||||
}
|
||||
|
||||
webrtc::CaptureCapability 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();
|
||||
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();
|
||||
|
||||
if (!error) {
|
||||
error = helper->mPtrViECapture->StartCapture(capnum, capability);
|
||||
}
|
||||
if (!error) {
|
||||
helper->mEngineIsRunning = true;
|
||||
}
|
||||
if (!error) {
|
||||
error = cap.VideoCapture()->StartCapture(capability);
|
||||
}
|
||||
if (!error) {
|
||||
engine->Startup();
|
||||
cap.VideoCapture()->RegisterCaptureDataCallback(*static_cast<webrtc::VideoCaptureDataCallback*>(*cbh));
|
||||
}
|
||||
});
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, error]() -> nsresult {
|
||||
|
|
@ -944,20 +870,27 @@ void
|
|||
CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
|
||||
const int& capnum)
|
||||
{
|
||||
if (EnsureInitialized(aCapEngine)) {
|
||||
mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
|
||||
mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
|
||||
mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
|
||||
mEngines[aCapEngine].mEngineIsRunning = false;
|
||||
|
||||
for (size_t i = 0; i < mCallbacks.Length(); i++) {
|
||||
if (mCallbacks[i]->mCapEngine == aCapEngine
|
||||
&& mCallbacks[i]->mCapturerId == capnum) {
|
||||
delete mCallbacks[i];
|
||||
mCallbacks.RemoveElementAt(i);
|
||||
if (auto engine = EnsureInitialized(aCapEngine)) {
|
||||
engine->WithEntry(capnum,[capnum](VideoEngine::CaptureEntry& cap){
|
||||
if (cap.VideoCapture()) {
|
||||
cap.VideoCapture()->StopCapture();
|
||||
cap.VideoCapture()->DeRegisterCaptureDataCallback();
|
||||
}
|
||||
if (cap.VideoRenderer()) {
|
||||
cap.VideoRenderer()->StopRender(capnum);
|
||||
}
|
||||
});
|
||||
// we're removing elements, iterate backwards
|
||||
for (size_t i = mCallbacks.Length(); i > 0; i--) {
|
||||
if (mCallbacks[i-1]->mCapEngine == aCapEngine
|
||||
&& mCallbacks[i-1]->mStreamId == (uint32_t) capnum) {
|
||||
delete mCallbacks[i-1];
|
||||
mCallbacks.RemoveElementAt(i-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
engine->RemoveRenderer(capnum);
|
||||
engine->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1077,7 +1010,7 @@ CamerasParent::~CamerasParent()
|
|||
// That runnable takes a ref to us, so it must have finished
|
||||
// by the time we get here.
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
MOZ_ASSERT(!mEngines[i].mEngine);
|
||||
MOZ_ASSERT(!mEngines[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,21 @@
|
|||
#define mozilla_CamerasParent_h
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "VideoEngine.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/camera/PCamerasParent.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/ShmemPool.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "webrtc/modules/video_capture/video_capture.h"
|
||||
#include "webrtc/modules/video_render/video_render_impl.h"
|
||||
#include "webrtc/modules/video_capture/video_capture_defines.h"
|
||||
#include "webrtc/common_video/include/incoming_video_stream.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"
|
||||
|
|
@ -29,60 +31,43 @@ namespace camera {
|
|||
|
||||
class CamerasParent;
|
||||
|
||||
class CallbackHelper : public webrtc::ExternalRenderer
|
||||
class CallbackHelper :
|
||||
public webrtc::VideoRenderCallback,
|
||||
public webrtc::VideoCaptureDataCallback
|
||||
{
|
||||
public:
|
||||
CallbackHelper(CaptureEngine aCapEng, int aCapId, CamerasParent *aParent)
|
||||
: mCapEngine(aCapEng), mCapturerId(aCapId), mParent(aParent) {};
|
||||
CallbackHelper(CaptureEngine aCapEng, uint32_t aStreamId, CamerasParent *aParent)
|
||||
: mCapEngine(aCapEng), mStreamId(aStreamId), 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; };
|
||||
virtual int32_t RenderFrame(const uint32_t aStreamId, const webrtc::VideoFrame& video_frame) override;
|
||||
|
||||
// From VideoCaptureCallback
|
||||
virtual void OnIncomingCapturedFrame(const int32_t id, const webrtc::VideoFrame& videoFrame) override;
|
||||
virtual void OnCaptureDelayChanged(const int32_t id, const int32_t delay) override;
|
||||
|
||||
// TODO(@@NG) This is now part of webrtc::VideoRenderer, not in the webrtc::VideoRenderCallback
|
||||
// virtual bool IsTextureSupported() const override { return false; };
|
||||
//
|
||||
// virtual bool SmoothsRenderedFrames() const override { return false; }
|
||||
|
||||
friend CamerasParent;
|
||||
|
||||
private:
|
||||
CaptureEngine mCapEngine;
|
||||
int mCapturerId;
|
||||
uint32_t mStreamId;
|
||||
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
|
||||
class InputObserver : public webrtc::VideoInputFeedBack
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InputObserver)
|
||||
|
||||
explicit InputObserver(CamerasParent* aParent)
|
||||
: mParent(aParent) {};
|
||||
virtual void DeviceChange();
|
||||
virtual void OnDeviceChange();
|
||||
|
||||
friend CamerasParent;
|
||||
|
||||
|
|
@ -113,7 +98,7 @@ public:
|
|||
const int&) override;
|
||||
virtual bool RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
|
||||
virtual bool RecvStartCapture(const CaptureEngine&, const int&,
|
||||
const CaptureCapability&) override;
|
||||
const VideoCaptureCapability&) override;
|
||||
virtual bool RecvStopCapture(const CaptureEngine&, const int&) override;
|
||||
virtual bool RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
|
||||
virtual bool RecvAllDone() override;
|
||||
|
|
@ -128,13 +113,10 @@ public:
|
|||
|
||||
// helper to forward to the PBackground thread
|
||||
int DeliverFrameOverIPC(CaptureEngine capEng,
|
||||
int cap_id,
|
||||
uint32_t aStreamId,
|
||||
ShmemBuffer buffer,
|
||||
unsigned char* altbuffer,
|
||||
size_t size,
|
||||
uint32_t time_stamp,
|
||||
int64_t ntp_time,
|
||||
int64_t render_time);
|
||||
VideoFrameProperties& aProps);
|
||||
|
||||
|
||||
CamerasParent();
|
||||
|
|
@ -147,14 +129,14 @@ protected:
|
|||
int ReleaseCaptureDevice(const CaptureEngine& aCapEngine, const int& capnum);
|
||||
|
||||
bool SetupEngine(CaptureEngine aCapEngine);
|
||||
bool EnsureInitialized(int aEngine);
|
||||
VideoEngine* 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];
|
||||
RefPtr<VideoEngine> mEngines[CaptureEngine::MaxEngine];
|
||||
nsTArray<CallbackHelper*> mCallbacks;
|
||||
|
||||
// image buffers
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include "nsIObserver.h"
|
||||
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/video_engine/include/vie_base.h"
|
||||
|
||||
#include "webrtc/call.h"
|
||||
#include "webrtc/video/overuse_frame_detector.h"
|
||||
extern mozilla::LazyLogModule gLoadManagerLog;
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -77,7 +77,7 @@ private:
|
|||
};
|
||||
|
||||
class LoadManager final : public webrtc::CPULoadStateCallbackInvoker,
|
||||
public webrtc::CpuOveruseObserver
|
||||
public webrtc::LoadObserver
|
||||
{
|
||||
public:
|
||||
explicit LoadManager(LoadManagerSingleton* aManager)
|
||||
|
|
@ -93,13 +93,14 @@ public:
|
|||
{
|
||||
mManager->RemoveObserver(aObserver);
|
||||
}
|
||||
void OveruseDetected() override
|
||||
|
||||
void OnLoadUpdate(webrtc::LoadObserver::Load load_state) override
|
||||
{
|
||||
mManager->OveruseDetected();
|
||||
}
|
||||
void NormalUsage() override
|
||||
{
|
||||
mManager->NormalUsage();
|
||||
if (load_state == webrtc::LoadObserver::kOveruse) {
|
||||
mManager->OveruseDetected();
|
||||
} else if (load_state == webrtc::LoadObserver::kUnderuse) {
|
||||
mManager->NormalUsage();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ using mozilla::camera::CaptureEngine from "mozilla/media/CamerasTypes.h";
|
|||
namespace mozilla {
|
||||
namespace camera {
|
||||
|
||||
struct CaptureCapability
|
||||
// IPC analog for webrtc::VideoCaptureCapability
|
||||
struct VideoCaptureCapability
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
|
|
@ -21,6 +22,32 @@ struct CaptureCapability
|
|||
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
|
||||
uint32_t bufferSize;
|
||||
// From webrtc::VideoFrame
|
||||
uint32_t timeStamp;
|
||||
int64_t ntpTimeMs;
|
||||
int64_t renderTimeMs;
|
||||
// See webrtc/**/rotation.h
|
||||
int rotation;
|
||||
int yAllocatedSize;
|
||||
int uAllocatedSize;
|
||||
int vAllocatedSize;
|
||||
// From webrtc::VideoFrameBuffer
|
||||
int width;
|
||||
int height;
|
||||
int yStride;
|
||||
int uStride;
|
||||
int vStride;
|
||||
};
|
||||
|
||||
async protocol PCameras
|
||||
{
|
||||
manager PBackground;
|
||||
|
|
@ -28,14 +55,13 @@ 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 cap_id,
|
||||
Shmem buffer, size_t size, uint32_t time_stamp,
|
||||
int64_t ntp_time, int64_t render_time);
|
||||
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(CaptureCapability cap);
|
||||
async ReplyGetCaptureCapability(VideoCaptureCapability cap);
|
||||
async ReplyGetCaptureDevice(nsCString device_name, nsCString device_id, bool scary);
|
||||
async ReplyFailure();
|
||||
async ReplySuccess();
|
||||
|
|
@ -45,12 +71,13 @@ parent:
|
|||
async NumberOfCaptureDevices(CaptureEngine engine);
|
||||
async NumberOfCapabilities(CaptureEngine engine, nsCString deviceUniqueIdUTF8);
|
||||
|
||||
async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8, int capability_number);
|
||||
async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8,
|
||||
int capability_number);
|
||||
async GetCaptureDevice(CaptureEngine engine, int num);
|
||||
|
||||
async AllocateCaptureDevice(CaptureEngine engine, nsCString unique_idUTF8, nsCString origin);
|
||||
async ReleaseCaptureDevice(CaptureEngine engine, int numdev);
|
||||
async StartCapture(CaptureEngine engine, int numdev, CaptureCapability capability);
|
||||
async StartCapture(CaptureEngine engine, int numdev, VideoCaptureCapability capability);
|
||||
async StopCapture(CaptureEngine engine, int numdev);
|
||||
// transfers frame back
|
||||
async ReleaseFrame(Shmem s);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ mozilla::ShmemBuffer ShmemPool::GetIfAvailable(size_t aSize)
|
|||
|
||||
MOZ_ASSERT(res.mShmem.IsWritable(), "Pool in Shmem is not writable?");
|
||||
|
||||
if (res.mShmem.Size<char>() < aSize) {
|
||||
if (res.mShmem.Size<uint8_t>() < aSize) {
|
||||
LOG(("Free Shmem but not of the right size"));
|
||||
return ShmemBuffer();
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ void ShmemPool::Put(ShmemBuffer&& aShmem)
|
|||
#ifdef DEBUG
|
||||
size_t poolUse = mShmemPool.Length() - mPoolFree;
|
||||
if (poolUse > 0) {
|
||||
LOG(("ShmemPool usage reduced to %d buffers", poolUse));
|
||||
LOG_VERBOSE(("ShmemPool usage reduced to %d buffers", poolUse));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ public:
|
|||
return mInitialized;
|
||||
}
|
||||
|
||||
char* GetBytes() {
|
||||
return mShmem.get<char>();
|
||||
uint8_t * GetBytes() {
|
||||
return mShmem.get<uint8_t>();
|
||||
}
|
||||
|
||||
mozilla::ipc::Shmem& Get() {
|
||||
|
|
|
|||
185
dom/media/systemservices/VideoEngine.cpp
Normal file
185
dom/media/systemservices/VideoEngine.cpp
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "VideoEngine.h"
|
||||
#include "webrtc/video_engine/browser_capture_impl.h"
|
||||
#ifdef WEBRTC_ANDROID
|
||||
#include "webrtc/modules/video_capture/video_capture.h"
|
||||
#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
|
||||
#include "webrtc/modules/video_render/video_render.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace camera {
|
||||
|
||||
#undef LOG
|
||||
#undef LOG_ENABLED
|
||||
mozilla::LazyLogModule gVideoEngineLog("VideoEngine");
|
||||
#define LOG(args) MOZ_LOG(gVideoEngineLog, mozilla::LogLevel::Debug, args)
|
||||
#define LOG_ENABLED() MOZ_LOG_TEST(gVideoEngineLog, mozilla::LogLevel::Debug)
|
||||
|
||||
int VideoEngine::sId = 0;
|
||||
|
||||
#if defined(ANDROID)
|
||||
int VideoEngine::SetAndroidObjects(JavaVM* javaVM) {
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
||||
if (webrtc::SetCaptureAndroidVM(javaVM) != 0) {
|
||||
LOG(("Could not set capture Android VM"));
|
||||
return -1;
|
||||
}
|
||||
#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
|
||||
if (webrtc::SetRenderAndroidVM(javaVM) != 0) {
|
||||
LOG(("Could not set render Android VM"));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
VideoEngine::CreateVideoCapture(int32_t& id, const char* deviceUniqueIdUTF8) {
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
id = GenerateId();
|
||||
LOG(("CaptureDeviceInfo.type=%s id=%d",mCaptureDevInfo.TypeName(),id));
|
||||
CaptureEntry entry = {-1,nullptr,nullptr};
|
||||
|
||||
if (mCaptureDevInfo.type == webrtc::CaptureDeviceType::Camera) {
|
||||
entry = CaptureEntry(id,
|
||||
webrtc::VideoCaptureFactory::Create(id, deviceUniqueIdUTF8),
|
||||
nullptr);
|
||||
} else {
|
||||
#ifndef WEBRTC_ANDROID
|
||||
entry = CaptureEntry(
|
||||
id,
|
||||
webrtc::DesktopCaptureImpl::Create(id, deviceUniqueIdUTF8, mCaptureDevInfo.type),
|
||||
nullptr);
|
||||
#else
|
||||
MOZ_ASSERT("CreateVideoCapture NO DESKTOP CAPTURE IMPL ON ANDROID" == nullptr);
|
||||
#endif
|
||||
}
|
||||
mCaps.emplace(id,std::move(entry));
|
||||
}
|
||||
|
||||
int
|
||||
VideoEngine::ReleaseVideoCapture(const int32_t id) {
|
||||
bool found = false;
|
||||
WithEntry(id, [&found](CaptureEntry& cap) {
|
||||
cap.mVideoCaptureModule = nullptr;
|
||||
found = true;
|
||||
});
|
||||
return found ? 0 : (-1);
|
||||
}
|
||||
|
||||
std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo>
|
||||
VideoEngine::GetOrCreateVideoCaptureDeviceInfo() {
|
||||
if (mDeviceInfo) {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
switch (mCaptureDevInfo.type) {
|
||||
case webrtc::CaptureDeviceType::Camera: {
|
||||
mDeviceInfo.reset(webrtc::VideoCaptureFactory::CreateDeviceInfo(0));
|
||||
break;
|
||||
}
|
||||
case webrtc::CaptureDeviceType::Browser: {
|
||||
mDeviceInfo.reset(webrtc::BrowserDeviceInfoImpl::CreateDeviceInfo());
|
||||
break;
|
||||
}
|
||||
// Window, Application, and Screen types are handled by DesktopCapture
|
||||
case webrtc::CaptureDeviceType::Window:
|
||||
case webrtc::CaptureDeviceType::Application:
|
||||
case webrtc::CaptureDeviceType::Screen: {
|
||||
#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
|
||||
mDeviceInfo.reset(webrtc::DesktopCaptureImpl::CreateDeviceInfo(mId,mCaptureDevInfo.type));
|
||||
#else
|
||||
MOZ_ASSERT("GetVideoCaptureDeviceInfo NO DESKTOP CAPTURE IMPL ON ANDROID" == nullptr);
|
||||
mDeviceInfo.reset();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
void
|
||||
VideoEngine::RemoveRenderer(int capnum) {
|
||||
WithEntry(capnum, [](CaptureEntry& cap) {
|
||||
cap.mVideoRender = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
const UniquePtr<const webrtc::Config>&
|
||||
VideoEngine::GetConfiguration() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
RefPtr<VideoEngine> VideoEngine::Create(UniquePtr<const webrtc::Config>&& aConfig) {
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
LOG(("Creating new VideoEngine with CaptureDeviceType %s",
|
||||
aConfig->Get<webrtc::CaptureDeviceInfo>().TypeName()));
|
||||
RefPtr<VideoEngine> engine(new VideoEngine(std::move(aConfig)));
|
||||
return engine;
|
||||
}
|
||||
|
||||
VideoEngine::CaptureEntry::CaptureEntry(int32_t aCapnum,
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> aCapture,
|
||||
webrtc::VideoRender * aRenderer):
|
||||
mCapnum(aCapnum),
|
||||
mVideoCaptureModule(aCapture),
|
||||
mVideoRender(aRenderer)
|
||||
{}
|
||||
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule>
|
||||
VideoEngine::CaptureEntry::VideoCapture() {
|
||||
return mVideoCaptureModule;
|
||||
}
|
||||
|
||||
const UniquePtr<webrtc::VideoRender>&
|
||||
VideoEngine::CaptureEntry::VideoRenderer() {
|
||||
if (!mVideoRender) {
|
||||
MOZ_ASSERT(mCapnum != -1);
|
||||
// Create a VideoRender on demand
|
||||
mVideoRender = UniquePtr<webrtc::VideoRender>(
|
||||
webrtc::VideoRender::CreateVideoRender(mCapnum,nullptr,false,webrtc::kRenderExternal));
|
||||
}
|
||||
return mVideoRender;
|
||||
}
|
||||
|
||||
int32_t
|
||||
VideoEngine::CaptureEntry::Capnum() const {
|
||||
return mCapnum;
|
||||
}
|
||||
|
||||
bool VideoEngine::WithEntry(const int32_t entryCapnum,
|
||||
const std::function<void(CaptureEntry &entry)>&& fn) {
|
||||
auto it = mCaps.find(entryCapnum);
|
||||
if (it == mCaps.end()) {
|
||||
return false;
|
||||
}
|
||||
fn(it->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
VideoEngine::GenerateId() {
|
||||
// XXX Something better than this (a map perhaps, or a simple boolean TArray, given
|
||||
// the number in-use is O(1) normally!)
|
||||
return mId = sId++;
|
||||
}
|
||||
|
||||
VideoEngine::VideoEngine(UniquePtr<const webrtc::Config>&& aConfig):
|
||||
mCaptureDevInfo(aConfig->Get<webrtc::CaptureDeviceInfo>()),
|
||||
mDeviceInfo(nullptr),
|
||||
mConfig(std::move(aConfig))
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
104
dom/media/systemservices/VideoEngine.h
Normal file
104
dom/media/systemservices/VideoEngine.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- 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_VideoEngine_h
|
||||
#define mozilla_VideoEngine_h
|
||||
|
||||
#include "MediaEngine.h"
|
||||
#include "VideoFrameUtils.h"
|
||||
#include "mozilla/media/MediaUtils.h"
|
||||
#include "webrtc/common.h"
|
||||
#include "webrtc/modules/video_capture/video_capture_impl.h"
|
||||
#include "webrtc/modules/video_render/video_render.h"
|
||||
#include "webrtc/modules/video_capture/video_capture_defines.h"
|
||||
#include "webrtc/modules/video_capture/video_capture_factory.h"
|
||||
#include "webrtc/video_engine/desktop_capture_impl.h"
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace mozilla {
|
||||
namespace camera {
|
||||
|
||||
// Historically the video engine was part of webrtc
|
||||
// it was removed (and reimplemented in Talk)
|
||||
class VideoEngine
|
||||
{
|
||||
private:
|
||||
virtual ~VideoEngine (){};
|
||||
|
||||
public:
|
||||
VideoEngine (){};
|
||||
NS_INLINE_DECL_REFCOUNTING(VideoEngine)
|
||||
|
||||
static RefPtr<VideoEngine> Create(UniquePtr<const webrtc::Config>&& aConfig);
|
||||
#if defined(ANDROID)
|
||||
static int SetAndroidObjects(JavaVM* javaVM);
|
||||
#endif
|
||||
void CreateVideoCapture(int32_t& id, const char* deviceUniqueIdUTF8);
|
||||
|
||||
int ReleaseVideoCapture(const int32_t id);
|
||||
|
||||
// VideoEngine is responsible for any cleanup in its modules
|
||||
static void Delete(VideoEngine * engine) { }
|
||||
|
||||
/** Returns or creates a new new DeviceInfo.
|
||||
* It is cached to prevent repeated lengthy polling for "realness"
|
||||
* of the hardware devices. This could be handled in a more elegant
|
||||
* way in the future.
|
||||
* @return on failure the shared_ptr will be null, otherwise it will contain a DeviceInfo.
|
||||
* @see bug 1305212 https://bugzilla.mozilla.org/show_bug.cgi?id=1305212
|
||||
*/
|
||||
std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo> GetOrCreateVideoCaptureDeviceInfo();
|
||||
|
||||
void RemoveRenderer(int capnum);
|
||||
|
||||
const UniquePtr<const webrtc::Config>& GetConfiguration();
|
||||
|
||||
void Startup() {
|
||||
mIsRunning = true;
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
bool IsRunning() const {
|
||||
return mIsRunning;
|
||||
}
|
||||
|
||||
class CaptureEntry {
|
||||
public:
|
||||
CaptureEntry(int32_t aCapnum,
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> aCapture,
|
||||
webrtc::VideoRender* aRenderer);
|
||||
int32_t Capnum() const;
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> VideoCapture();
|
||||
const UniquePtr<webrtc::VideoRender> & VideoRenderer();
|
||||
private:
|
||||
int32_t mCapnum;
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> mVideoCaptureModule;
|
||||
UniquePtr<webrtc::VideoRender> mVideoRender;
|
||||
friend class VideoEngine;
|
||||
};
|
||||
|
||||
// Returns true iff an entry for capnum exists
|
||||
bool WithEntry(const int32_t entryCapnum, const std::function<void(CaptureEntry &entry)>&& fn);
|
||||
|
||||
private:
|
||||
explicit VideoEngine(UniquePtr<const webrtc::Config>&& aConfig);
|
||||
bool mIsRunning;
|
||||
int32_t mId;
|
||||
webrtc::CaptureDeviceInfo mCaptureDevInfo;
|
||||
std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo> mDeviceInfo;
|
||||
UniquePtr<const webrtc::Config> mConfig;
|
||||
std::map<int32_t, CaptureEntry> mCaps;
|
||||
|
||||
int32_t GenerateId();
|
||||
static int32_t sId;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
92
dom/media/systemservices/VideoFrameUtils.cpp
Normal file
92
dom/media/systemservices/VideoFrameUtils.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "VideoFrameUtils.h"
|
||||
#include "webrtc/video_frame.h"
|
||||
#include "mozilla/ShmemPool.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
size_t
|
||||
VideoFrameUtils::TotalRequiredBufferSize(
|
||||
const webrtc::VideoFrame& aVideoFrame)
|
||||
{
|
||||
static const webrtc::PlaneType kPlanes[] =
|
||||
{webrtc::kYPlane, webrtc::kUPlane, webrtc::kVPlane};
|
||||
if (aVideoFrame.IsZeroSize()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t sum = 0;
|
||||
for (auto plane : kPlanes) {
|
||||
sum += aVideoFrame.allocated_size(plane);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void VideoFrameUtils::InitFrameBufferProperties(
|
||||
const webrtc::VideoFrame& aVideoFrame,
|
||||
camera::VideoFrameProperties& aDestProps)
|
||||
{
|
||||
// The VideoFrameBuffer image data stored in the accompanying buffer
|
||||
// the buffer is at least this size of larger.
|
||||
aDestProps.bufferSize() = TotalRequiredBufferSize(aVideoFrame);
|
||||
|
||||
aDestProps.timeStamp() = aVideoFrame.timestamp();
|
||||
aDestProps.ntpTimeMs() = aVideoFrame.ntp_time_ms();
|
||||
aDestProps.renderTimeMs() = aVideoFrame.render_time_ms();
|
||||
|
||||
aDestProps.rotation() = aVideoFrame.rotation();
|
||||
|
||||
aDestProps.yAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
|
||||
aDestProps.uAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
|
||||
aDestProps.vAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
|
||||
|
||||
aDestProps.width() = aVideoFrame.width();
|
||||
aDestProps.height() = aVideoFrame.height();
|
||||
|
||||
aDestProps.yStride() = aVideoFrame.stride(webrtc::kYPlane);
|
||||
aDestProps.uStride() = aVideoFrame.stride(webrtc::kUPlane);
|
||||
aDestProps.vStride() = aVideoFrame.stride(webrtc::kVPlane);
|
||||
}
|
||||
|
||||
void VideoFrameUtils::CopyVideoFrameBuffers(uint8_t* aDestBuffer,
|
||||
const size_t aDestBufferSize,
|
||||
const webrtc::VideoFrame& aFrame)
|
||||
{
|
||||
static const webrtc::PlaneType planes[] = {webrtc::kYPlane, webrtc::kUPlane, webrtc::kVPlane};
|
||||
|
||||
size_t aggregateSize = TotalRequiredBufferSize(aFrame);
|
||||
|
||||
MOZ_ASSERT(aDestBufferSize >= aggregateSize);
|
||||
|
||||
// If planes are ordered YUV and contiguous then do a single copy
|
||||
if ((aFrame.buffer(webrtc::kYPlane) != nullptr)
|
||||
// Check that the three planes are ordered
|
||||
&& (aFrame.buffer(webrtc::kYPlane) < aFrame.buffer(webrtc::kUPlane))
|
||||
&& (aFrame.buffer(webrtc::kUPlane) < aFrame.buffer(webrtc::kVPlane))
|
||||
// Check that the last plane ends at firstPlane[totalsize]
|
||||
&& (&aFrame.buffer(webrtc::kYPlane)[aggregateSize] == &aFrame.buffer(webrtc::kVPlane)[aFrame.allocated_size(webrtc::kVPlane)]))
|
||||
{
|
||||
memcpy(aDestBuffer,aFrame.buffer(webrtc::kYPlane),aggregateSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy each plane
|
||||
size_t offset = 0;
|
||||
for (auto plane: planes) {
|
||||
memcpy(&aDestBuffer[offset], aFrame.buffer(plane), aFrame.allocated_size(plane));
|
||||
offset += aFrame.allocated_size(plane);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoFrameUtils::CopyVideoFrameBuffers(ShmemBuffer& aDestShmem,
|
||||
const webrtc::VideoFrame& aVideoFrame)
|
||||
{
|
||||
CopyVideoFrameBuffers(aDestShmem.Get().get<uint8_t>(), aDestShmem.Get().Size<uint8_t>(), aVideoFrame);
|
||||
}
|
||||
|
||||
}
|
||||
51
dom/media/systemservices/VideoFrameUtils.h
Normal file
51
dom/media/systemservices/VideoFrameUtils.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- 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_VideoFrameUtil_h
|
||||
#define mozilla_VideoFrameUtil_h
|
||||
|
||||
#include "mozilla/camera/PCameras.h"
|
||||
|
||||
namespace webrtc {
|
||||
class VideoFrame;
|
||||
}
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
class ShmemBuffer;
|
||||
|
||||
// Util methods for working with webrtc::VideoFrame(s) and
|
||||
// the IPC classes that are used to deliver their contents to the
|
||||
// MediaEnginge
|
||||
|
||||
class VideoFrameUtils {
|
||||
public:
|
||||
|
||||
// Returns the total number of bytes necessary to copy a VideoFrame's buffer
|
||||
// across all planes.
|
||||
static size_t TotalRequiredBufferSize(const webrtc::VideoFrame & frame);
|
||||
|
||||
// Initializes a camera::VideoFrameProperties from a VideoFrameBuffer
|
||||
static void InitFrameBufferProperties(const webrtc::VideoFrame& aVideoFrame,
|
||||
camera::VideoFrameProperties & aDestProperties);
|
||||
|
||||
// Copies the buffers out of a VideoFrameBuffer into a buffer.
|
||||
// Attempts to make as few memcopies as possible.
|
||||
static void CopyVideoFrameBuffers(uint8_t * aDestBuffer,
|
||||
const size_t aDestBufferSize,
|
||||
const webrtc::VideoFrame & aVideoFrame);
|
||||
|
||||
// Copies the buffers in a VideoFrameBuffer into a Shmem
|
||||
// returns the eno from the underlying memcpy.
|
||||
static void CopyVideoFrameBuffers(ShmemBuffer & aDestShmem,
|
||||
const webrtc::VideoFrame & aVideoFrame);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
|
@ -10,6 +10,8 @@ if CONFIG['MOZ_WEBRTC']:
|
|||
'LoadManager.h',
|
||||
'LoadManagerFactory.h',
|
||||
'LoadMonitor.h',
|
||||
'VideoEngine.h',
|
||||
'VideoFrameUtils.h'
|
||||
]
|
||||
SOURCES += [
|
||||
'CamerasChild.cpp',
|
||||
|
|
@ -18,6 +20,8 @@ if CONFIG['MOZ_WEBRTC']:
|
|||
'LoadManagerFactory.cpp',
|
||||
'LoadMonitor.cpp',
|
||||
'ShmemPool.cpp',
|
||||
'VideoEngine.cpp',
|
||||
'VideoFrameUtils.cpp'
|
||||
]
|
||||
LOCAL_INCLUDES += [
|
||||
'/media/webrtc/signaling',
|
||||
|
|
@ -29,6 +33,9 @@ if CONFIG['OS_TARGET'] == 'WINNT':
|
|||
else:
|
||||
DEFINES['WEBRTC_POSIX'] = True
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
DEFINES['WEBRTC_ANDROID'] = True
|
||||
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
EXPORTS += [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue