зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1024300 - Allow GMPs to be segregated by origin. r=josh
This commit is contained in:
Родитель
711b5f3c6f
Коммит
418fcf0ab2
|
@ -420,5 +420,26 @@ GMPParent::ReadGMPMetaData()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::CanBeSharedCrossOrigin() const
|
||||
{
|
||||
return mOrigin.IsEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::CanBeUsedFrom(const nsAString& aOrigin) const
|
||||
{
|
||||
return (mOrigin.IsEmpty() && State() == GMPStateNotLoaded) ||
|
||||
mOrigin.Equals(aOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::SetOrigin(const nsAString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(!aOrigin.IsEmpty());
|
||||
MOZ_ASSERT(CanBeUsedFrom(aOrigin));
|
||||
mOrigin = aOrigin;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -56,6 +56,27 @@ public:
|
|||
nsIThread* GMPThread();
|
||||
#endif
|
||||
|
||||
// A GMP can either be a single instance shared across all origins (like
|
||||
// in the OpenH264 case), or we can require a new plugin instance for every
|
||||
// origin running the plugin (as in the EME plugin case).
|
||||
//
|
||||
// Plugins are associated with an origin by calling SetOrigin() before
|
||||
// loading.
|
||||
//
|
||||
// If a plugin has no origin specified and it is loaded, it is assumed to
|
||||
// be shared across origins.
|
||||
|
||||
// Specifies that a GMP can only work with the specified origin.
|
||||
void SetOrigin(const nsAString& aOrigin);
|
||||
|
||||
// Returns true if a plugin can be or is being used across multiple origins.
|
||||
bool CanBeSharedCrossOrigin() const;
|
||||
|
||||
// A GMP can be used from an origin if it's already been set to work with
|
||||
// that origin, or if it's not been set to work with any origin and has
|
||||
// not yet been loaded (i.e. it's not shared across origins).
|
||||
bool CanBeUsedFrom(const nsAString& aOrigin) const;
|
||||
|
||||
private:
|
||||
~GMPParent();
|
||||
bool EnsureProcessLoaded();
|
||||
|
@ -80,6 +101,9 @@ private:
|
|||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
#endif
|
||||
// Origin the plugin is assigned to, or empty if the the plugin is not
|
||||
// assigned to an origin.
|
||||
nsAutoString mOrigin;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -191,16 +191,23 @@ GeckoMediaPluginService::GetThread(nsIThread** aThread)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetGMPVideoDecoderVP8(GMPVideoHost** aOutVideoHost, GMPVideoDecoder** aGMPVD)
|
||||
GeckoMediaPluginService::GetGMPVideoDecoder(nsTArray<nsCString>* aTags,
|
||||
const nsAString& aOrigin,
|
||||
GMPVideoHost** aOutVideoHost,
|
||||
GMPVideoDecoder** aGMPVD)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
NS_ENSURE_ARG(aOutVideoHost);
|
||||
NS_ENSURE_ARG(aGMPVD);
|
||||
|
||||
if (mShuttingDownOnGMPThread) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(NS_LITERAL_CSTRING("decode-video"),
|
||||
NS_LITERAL_CSTRING("vp8"));
|
||||
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aOrigin,
|
||||
NS_LITERAL_CSTRING("decode-video"),
|
||||
*aTags);
|
||||
if (!gmp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -218,16 +225,23 @@ GeckoMediaPluginService::GetGMPVideoDecoderVP8(GMPVideoHost** aOutVideoHost, GMP
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetGMPVideoEncoderVP8(GMPVideoHost** aOutVideoHost, GMPVideoEncoder** aGMPVE)
|
||||
GeckoMediaPluginService::GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
|
||||
const nsAString& aOrigin,
|
||||
GMPVideoHost** aOutVideoHost,
|
||||
GMPVideoEncoder** aGMPVE)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
NS_ENSURE_ARG(aOutVideoHost);
|
||||
NS_ENSURE_ARG(aGMPVE);
|
||||
|
||||
if (mShuttingDownOnGMPThread) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(NS_LITERAL_CSTRING("encode-video"),
|
||||
NS_LITERAL_CSTRING("vp8"));
|
||||
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aOrigin,
|
||||
NS_LITERAL_CSTRING("encode-video"),
|
||||
*aTags);
|
||||
if (!gmp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -259,30 +273,50 @@ GeckoMediaPluginService::UnloadPlugins()
|
|||
}
|
||||
|
||||
GMPParent*
|
||||
GeckoMediaPluginService::SelectPluginForAPI(const nsCString& aAPI,
|
||||
const nsCString& aTag)
|
||||
GeckoMediaPluginService::SelectPluginForAPI(const nsAString& aOrigin,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
|
||||
GMPParent* gmp = SelectPluginFromListForAPI(aAPI, aTag);
|
||||
GMPParent* gmp = SelectPluginFromListForAPI(aOrigin, aAPI, aTags);
|
||||
if (gmp) {
|
||||
return gmp;
|
||||
}
|
||||
|
||||
RefreshPluginList();
|
||||
|
||||
return SelectPluginFromListForAPI(aAPI, aTag);
|
||||
return SelectPluginFromListForAPI(aOrigin, aAPI, aTags);
|
||||
}
|
||||
|
||||
GMPParent*
|
||||
GeckoMediaPluginService::SelectPluginFromListForAPI(const nsCString& aAPI,
|
||||
const nsCString& aTag)
|
||||
GeckoMediaPluginService::SelectPluginFromListForAPI(const nsAString& aOrigin,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
|
||||
for (uint32_t i = 0; i < mPlugins.Length(); i++) {
|
||||
GMPParent* gmp = mPlugins[i];
|
||||
if (gmp->SupportsAPI(aAPI, aTag)) {
|
||||
bool supportsAllTags = true;
|
||||
for (uint32_t t = 0; t < aTags.Length(); t++) {
|
||||
const nsCString& tag = aTags[t];
|
||||
if (!gmp->SupportsAPI(aAPI, tag)) {
|
||||
supportsAllTags = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!supportsAllTags) {
|
||||
continue;
|
||||
}
|
||||
if (aOrigin.IsEmpty()) {
|
||||
if (gmp->CanBeSharedCrossOrigin()) {
|
||||
return gmp;
|
||||
}
|
||||
} else if (gmp->CanBeUsedFrom(aOrigin)) {
|
||||
if (!aOrigin.IsEmpty()) {
|
||||
gmp->SetOrigin(aOrigin);
|
||||
}
|
||||
return gmp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,12 @@ public:
|
|||
private:
|
||||
~GeckoMediaPluginService();
|
||||
|
||||
GMPParent* SelectPluginFromListForAPI(const nsCString& aAPI, const nsCString& aTag);
|
||||
GMPParent* SelectPluginForAPI(const nsCString& aAPI, const nsCString& aTag);
|
||||
GMPParent* SelectPluginFromListForAPI(const nsAString& aOrigin,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags);
|
||||
GMPParent* SelectPluginForAPI(const nsAString& aOrigin,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags);
|
||||
void UnloadPlugins();
|
||||
|
||||
void RefreshPluginList();
|
||||
|
|
|
@ -96,7 +96,7 @@ GMPVideoHostImpl::ActorDestroyed()
|
|||
mEncodedFrames[i - 1]->ActorDestroyed();
|
||||
mEncodedFrames.RemoveElementAt(i - 1);
|
||||
}
|
||||
mSharedMemMgr = nullptr;
|
||||
mSharedMemMgr = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -16,6 +16,7 @@ class GMPVideoHost;
|
|||
[ptr] native GMPVideoEncoder(GMPVideoEncoder);
|
||||
[ptr] native GMPVideoHost(GMPVideoHost);
|
||||
[ptr] native MessageLoop(MessageLoop);
|
||||
[ptr] native TagArray(nsTArray<nsCString>);
|
||||
|
||||
[uuid(BF5A9086-70F5-4D38-832D-1609BBF963CD)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
|
@ -24,11 +25,19 @@ interface mozIGeckoMediaPluginService : nsISupports
|
|||
// Callable from any thread.
|
||||
readonly attribute nsIThread thread;
|
||||
|
||||
// Returns a video decoder API object that should support VP8.
|
||||
// Returns a video decoder that supports the specified tags.
|
||||
// The array of tags should at least contain a codec tag, and optionally
|
||||
// other tags such as for EME keysystem.
|
||||
// Callable only on GMP thread.
|
||||
GMPVideoDecoder getGMPVideoDecoderVP8(out GMPVideoHost outVideoHost);
|
||||
GMPVideoDecoder getGMPVideoDecoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
|
||||
// Returns a video encoder API object that should support VP8.
|
||||
// Returns a video encoder that supports the specified tags.
|
||||
// The array of tags should at least contain a codec tag, and optionally
|
||||
// other tags.
|
||||
// Callable only on GMP thread.
|
||||
GMPVideoEncoder getGMPVideoEncoderVP8(out GMPVideoHost outVideoHost);
|
||||
GMPVideoEncoder getGMPVideoEncoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
};
|
||||
|
|
|
@ -123,7 +123,12 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
|||
GMPVideoHost* host = nullptr;
|
||||
GMPVideoEncoder* gmp = nullptr;
|
||||
|
||||
nsresult rv = mMPS->GetGMPVideoEncoderVP8(&host, &gmp);
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
nsresult rv = mMPS->GetGMPVideoEncoder(&tags,
|
||||
NS_LITERAL_STRING(""),
|
||||
&host,
|
||||
&gmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
@ -458,8 +463,12 @@ WebrtcGmpVideoDecoder::InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
|
|||
GMPVideoHost* host = nullptr;
|
||||
GMPVideoDecoder* gmp = nullptr;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(mMPS->GetGMPVideoDecoderVP8(&host, &gmp))))
|
||||
{
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
if (NS_WARN_IF(NS_FAILED(mMPS->GetGMPVideoDecoder(&tags,
|
||||
NS_LITERAL_STRING(""),
|
||||
&host,
|
||||
&gmp)))) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче