mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1037754: Query GMPService to determine if H.264 is available r=cpearce
This commit is contained in:
parent
f6fb38029f
commit
0ff7099b5e
@ -14,6 +14,7 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -113,6 +114,10 @@ GeckoMediaPluginService::Init()
|
||||
MOZ_ASSERT(obsService);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false)));
|
||||
|
||||
// Kick off scanning for plugins
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
unused << GetThread(getter_AddRefs(thread));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -255,6 +260,7 @@ GeckoMediaPluginService::UnloadPlugins()
|
||||
MOZ_ASSERT(!mShuttingDownOnGMPThread);
|
||||
mShuttingDownOnGMPThread = true;
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (uint32_t i = 0; i < mPlugins.Length(); i++) {
|
||||
mPlugins[i]->UnloadProcess();
|
||||
}
|
||||
@ -330,13 +336,28 @@ GeckoMediaPluginService::RemovePluginDirectory(const nsAString& aDirectory)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginService::HasPluginForAPI(const nsAString& aOrigin,
|
||||
const nsACString& aAPI,
|
||||
nsTArray<nsCString>* aTags,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
NS_ENSURE_ARG(aResult);
|
||||
|
||||
nsCString temp(aAPI);
|
||||
GMPParent *parent = SelectPluginForAPI(aOrigin, temp, *aTags);
|
||||
*aResult = !!parent;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GMPParent*
|
||||
GeckoMediaPluginService::SelectPluginForAPI(const nsAString& aOrigin,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (uint32_t i = 0; i < mPlugins.Length(); i++) {
|
||||
GMPParent* gmp = mPlugins[i];
|
||||
bool supportsAllTags = true;
|
||||
@ -402,6 +423,7 @@ GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
|
||||
return;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
mPlugins.AppendElement(gmp);
|
||||
}
|
||||
|
||||
@ -416,6 +438,7 @@ GeckoMediaPluginService::RemoveOnGMPThread(const nsAString& aDirectory)
|
||||
return;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (uint32_t i = 0; i < mPlugins.Length(); ++i) {
|
||||
nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory();
|
||||
bool equals;
|
||||
|
@ -69,8 +69,8 @@ private:
|
||||
bool mAdd;
|
||||
};
|
||||
|
||||
Mutex mMutex; // Protects mGMPThread and mShuttingDown and mPlugins
|
||||
nsTArray<nsRefPtr<GMPParent>> mPlugins;
|
||||
Mutex mMutex; // Protects mGMPThread and mShuttingDown
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
bool mShuttingDown;
|
||||
bool mShuttingDownOnGMPThread;
|
||||
|
@ -21,7 +21,7 @@ class GMPVideoHost;
|
||||
[ptr] native MessageLoop(MessageLoop);
|
||||
[ptr] native TagArray(nsTArray<nsCString>);
|
||||
|
||||
[scriptable, uuid(7cef50ca-7a0f-41f2-9560-47abf709f0d7)]
|
||||
[scriptable, uuid(a9b826da-725a-4b81-814f-b715445188f2)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -29,6 +29,15 @@ interface mozIGeckoMediaPluginService : nsISupports
|
||||
*/
|
||||
readonly attribute nsIThread thread;
|
||||
|
||||
/**
|
||||
* Get a plugin that supports the specified tags.
|
||||
* Callable on any thread
|
||||
*/
|
||||
[noscript]
|
||||
boolean hasPluginForAPI([optional] in AString origin,
|
||||
in ACString api,
|
||||
in TagArray tags);
|
||||
|
||||
/**
|
||||
* Get a video decoder that supports the specified tags.
|
||||
* The array of tags should at least contain a codec tag, and optionally
|
||||
|
@ -146,7 +146,7 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
GMPVideoEncoderProxy* gmp = nullptr;
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
nsresult rv = mMPS->GetGMPVideoEncoder(&tags,
|
||||
NS_LITERAL_STRING(""),
|
||||
&host,
|
||||
@ -178,7 +178,7 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
|
||||
// H.264 mode 1 only supported so far
|
||||
GMPErr err = mGMP->InitEncode(codec, codecSpecific, this, 1, 256000 /*aMaxPayloadSize*/);
|
||||
GMPErr err = mGMP->InitEncode(codec, codecSpecific, this, 1, 1024*1024 /*aMaxPayloadSize*/);
|
||||
if (err != GMPNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
@ -418,7 +418,7 @@ WebrtcGmpVideoDecoder::InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
GMPVideoDecoderProxy* gmp = nullptr;
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
if (NS_WARN_IF(NS_FAILED(mMPS->GetGMPVideoDecoder(&tags,
|
||||
NS_LITERAL_STRING(""),
|
||||
&host,
|
||||
|
@ -89,6 +89,7 @@ using namespace mozilla;
|
||||
using namespace CSF;
|
||||
|
||||
VcmSIPCCBinding * VcmSIPCCBinding::gSelf = nullptr;
|
||||
bool VcmSIPCCBinding::gInitGmpCodecs = false;
|
||||
int VcmSIPCCBinding::gAudioCodecMask = 0;
|
||||
int VcmSIPCCBinding::gVideoCodecMask = 0;
|
||||
int VcmSIPCCBinding::gVideoCodecGmpMask = 0;
|
||||
@ -228,12 +229,6 @@ void VcmSIPCCBinding::setVideoCodecs(int codecMask)
|
||||
VcmSIPCCBinding::gVideoCodecMask = codecMask;
|
||||
}
|
||||
|
||||
void VcmSIPCCBinding::addVideoCodecsGmp(int codecMask)
|
||||
{
|
||||
CSFLogDebug(logTag, "ADDING VIDEO: %d", codecMask);
|
||||
VcmSIPCCBinding::gVideoCodecGmpMask |= codecMask;
|
||||
}
|
||||
|
||||
int VcmSIPCCBinding::getAudioCodecs()
|
||||
{
|
||||
return VcmSIPCCBinding::gAudioCodecMask;
|
||||
@ -244,9 +239,76 @@ int VcmSIPCCBinding::getVideoCodecs()
|
||||
return VcmSIPCCBinding::gVideoCodecMask;
|
||||
}
|
||||
|
||||
static void GMPDummy() {};
|
||||
|
||||
bool VcmSIPCCBinding::scanForGmpCodecs()
|
||||
{
|
||||
if (!gSelf) {
|
||||
return false;
|
||||
}
|
||||
if (!gSelf->mGMPService) {
|
||||
gSelf->mGMPService = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (!gSelf->mGMPService) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX find a way to a) do this earlier, b) not block mainthread
|
||||
// Perhaps fire on first RTCPeerconnection creation, and block
|
||||
// processing (async) CreateOffer or CreateAnswer's until it has returned.
|
||||
// Since they're already async, it's easy to avoid starting them there.
|
||||
// However, we might like to do it even earlier, perhaps.
|
||||
|
||||
// XXX We shouldn't be blocking MainThread on the GMP thread!
|
||||
// This initiates the scan for codecs
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
nsresult rv = gSelf->mGMPService->GetThread(getter_AddRefs(thread));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
// presumes that all GMP dir scans have been queued for the GMPThread
|
||||
RUN_ON_THREAD(thread,
|
||||
WrapRunnableNM(&GMPDummy),
|
||||
NS_DISPATCH_SYNC);
|
||||
return true;
|
||||
}
|
||||
|
||||
int VcmSIPCCBinding::getVideoCodecsGmp()
|
||||
{
|
||||
return VcmSIPCCBinding::gVideoCodecGmpMask;
|
||||
if (!gInitGmpCodecs) {
|
||||
if (scanForGmpCodecs()) {
|
||||
gInitGmpCodecs = true;
|
||||
}
|
||||
}
|
||||
if (gInitGmpCodecs) {
|
||||
if (!gSelf->mGMPService) {
|
||||
gSelf->mGMPService = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
}
|
||||
if (gSelf->mGMPService) {
|
||||
// XXX I'd prefer if this was all known ahead of time...
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
|
||||
// H.264 only for now
|
||||
bool has_gmp;
|
||||
nsresult rv;
|
||||
rv = gSelf->mGMPService->HasPluginForAPI(NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_CSTRING("encode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_SUCCEEDED(rv) && has_gmp) {
|
||||
rv = gSelf->mGMPService->HasPluginForAPI(NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_CSTRING("decode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_SUCCEEDED(rv) && has_gmp) {
|
||||
return VCM_CODEC_RESOURCE_H264;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VcmSIPCCBinding::getVideoCodecsHw()
|
||||
|
@ -11,6 +11,7 @@ extern "C"
|
||||
}
|
||||
|
||||
#include "sigslot.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
|
||||
class nsIThread;
|
||||
class nsIEventTarget;
|
||||
@ -32,11 +33,12 @@ namespace CSF
|
||||
class StreamObserver
|
||||
{
|
||||
public:
|
||||
virtual void registerStream(cc_call_handle_t call, int streamId, bool isVideo) = 0;
|
||||
virtual void deregisterStream(cc_call_handle_t call, int streamId) = 0;
|
||||
virtual void dtmfBurst(int digit, int direction, int duration) = 0;
|
||||
virtual void sendIFrame(cc_call_handle_t call) = 0;
|
||||
virtual void registerStream(cc_call_handle_t call, int streamId, bool isVideo) = 0;
|
||||
virtual void deregisterStream(cc_call_handle_t call, int streamId) = 0;
|
||||
virtual void dtmfBurst(int digit, int direction, int duration) = 0;
|
||||
virtual void sendIFrame(cc_call_handle_t call) = 0;
|
||||
};
|
||||
|
||||
class VcmSIPCCBinding : public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
@ -58,35 +60,37 @@ namespace CSF
|
||||
|
||||
static void setAudioCodecs(int codecMask);
|
||||
static void setVideoCodecs(int codecMask);
|
||||
static void addVideoCodecsGmp(int codecMask);
|
||||
|
||||
static int getAudioCodecs();
|
||||
static int getVideoCodecs();
|
||||
static int getVideoCodecsGmp();
|
||||
static int getVideoCodecsHw();
|
||||
|
||||
static void setMainThread(nsIThread *thread);
|
||||
static nsIThread *getMainThread();
|
||||
static nsIEventTarget *getSTSThread();
|
||||
static void setMainThread(nsIThread *thread);
|
||||
static nsIThread *getMainThread();
|
||||
static nsIEventTarget *getSTSThread();
|
||||
|
||||
static void setSTSThread(nsIEventTarget *thread);
|
||||
static void setSTSThread(nsIEventTarget *thread);
|
||||
|
||||
static void connectCandidateSignal(mozilla::NrIceMediaStream* stream);
|
||||
static void connectCandidateSignal(mozilla::NrIceMediaStream* stream);
|
||||
|
||||
static nsCOMPtr<nsIPrefBranch> getPrefBranch();
|
||||
|
||||
static int gVideoCodecGmpMask;
|
||||
private:
|
||||
void CandidateReady(mozilla::NrIceMediaStream* stream,
|
||||
const std::string& candidate);
|
||||
static bool scanForGmpCodecs();
|
||||
void CandidateReady(mozilla::NrIceMediaStream* stream,
|
||||
const std::string& candidate);
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mGMPService;
|
||||
static VcmSIPCCBinding * gSelf;
|
||||
StreamObserver* streamObserver;
|
||||
MediaProviderObserver *mediaProviderObserver;
|
||||
static bool gInitGmpCodecs;
|
||||
static int gAudioCodecMask;
|
||||
static int gVideoCodecMask;
|
||||
static int gVideoCodecGmpMask;
|
||||
static nsIThread *gMainThread;
|
||||
static nsIEventTarget *gSTSThread;
|
||||
static nsIThread *gMainThread;
|
||||
static nsIEventTarget *gSTSThread;
|
||||
static nsCOMPtr<nsIPrefBranch> gBranch;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user