forked from mirrors/gecko-dev
Bug 1867542 - Reflect PEM changes to PEMFactory. r=jolin
Depends on D195135 Differential Revision: https://phabricator.services.mozilla.com/D195136
This commit is contained in:
parent
c863ef6478
commit
7c6eecefe0
2 changed files with 141 additions and 27 deletions
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "PEMFactory.h"
|
||||
|
||||
#include "PlatformEncoderModule.h"
|
||||
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
# include "AppleEncoderModule.h"
|
||||
#endif
|
||||
|
|
@ -32,15 +34,22 @@ namespace mozilla {
|
|||
|
||||
LazyLogModule sPEMLog("PlatformEncoderModule");
|
||||
|
||||
#define LOGE(fmt, ...) \
|
||||
MOZ_LOG(sPEMLog, mozilla::LogLevel::Error, \
|
||||
("[PEMFactory] %s: " fmt, __func__, ##__VA_ARGS__))
|
||||
#define LOG(fmt, ...) \
|
||||
MOZ_LOG(sPEMLog, mozilla::LogLevel::Debug, \
|
||||
("[PEMFactory] %s: " fmt, __func__, ##__VA_ARGS__))
|
||||
|
||||
PEMFactory::PEMFactory() {
|
||||
gfx::gfxVars::Initialize();
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
RefPtr<PlatformEncoderModule> m(new AppleEncoderModule());
|
||||
mModules.AppendElement(m);
|
||||
mCurrentPEMs.AppendElement(m);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mModules.AppendElement(new AndroidEncoderModule());
|
||||
mCurrentPEMs.AppendElement(new AndroidEncoderModule());
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
|
@ -68,38 +77,130 @@ PEMFactory::PEMFactory() {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool PEMFactory::SupportsMimeType(const nsACString& aMimeType) const {
|
||||
for (auto m : mModules) {
|
||||
if (m->SupportsMimeType(aMimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<MediaDataEncoder> PEMFactory::CreateEncoder(
|
||||
const CreateEncoderParams& aParams, const bool aHardwareNotAllowed) {
|
||||
const TrackInfo& info = aParams.mConfig;
|
||||
RefPtr<PlatformEncoderModule> m = FindPEM(info);
|
||||
const EncoderConfig& aConfig, const RefPtr<TaskQueue>& aTaskQueue) {
|
||||
RefPtr<PlatformEncoderModule> m = FindPEM(aConfig);
|
||||
if (!m) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return info.IsVideo() ? m->CreateVideoEncoder(aParams, aHardwareNotAllowed)
|
||||
: nullptr;
|
||||
return aConfig.IsVideo() ? m->CreateVideoEncoder(aConfig, aTaskQueue)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise>
|
||||
PEMFactory::CreateEncoderAsync(const EncoderConfig& aConfig,
|
||||
const RefPtr<TaskQueue>& aTaskQueue) {
|
||||
return CheckAndMaybeCreateEncoder(aConfig, 0, aTaskQueue);
|
||||
}
|
||||
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise>
|
||||
PEMFactory::CheckAndMaybeCreateEncoder(const EncoderConfig& aConfig,
|
||||
uint32_t aIndex,
|
||||
const RefPtr<TaskQueue>& aTaskQueue) {
|
||||
for (uint32_t i = aIndex; i < mCurrentPEMs.Length(); i++) {
|
||||
if (!mCurrentPEMs[i]->Supports(aConfig)) {
|
||||
continue;
|
||||
}
|
||||
return CreateEncoderWithPEM(mCurrentPEMs[i], aConfig, aTaskQueue)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[](RefPtr<MediaDataEncoder>&& aEncoder) {
|
||||
return PlatformEncoderModule::CreateEncoderPromise::
|
||||
CreateAndResolve(std::move(aEncoder), __func__);
|
||||
},
|
||||
[self = RefPtr{this}, i, config = aConfig, aTaskQueue,
|
||||
&aConfig](const MediaResult& aError) mutable {
|
||||
// Try the next PEM.
|
||||
return self->CheckAndMaybeCreateEncoder(aConfig, i + 1,
|
||||
aTaskQueue);
|
||||
});
|
||||
}
|
||||
return PlatformEncoderModule::CreateEncoderPromise::CreateAndReject(
|
||||
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||
nsPrintfCString("Error no encoder found for %d",
|
||||
static_cast<int>(aConfig.mCodec))
|
||||
.get()),
|
||||
__func__);
|
||||
}
|
||||
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise>
|
||||
PEMFactory::CreateEncoderWithPEM(PlatformEncoderModule* aPEM,
|
||||
const EncoderConfig& aConfig,
|
||||
const RefPtr<TaskQueue>& aTaskQueue) {
|
||||
MOZ_ASSERT(aPEM);
|
||||
MediaResult result = NS_OK;
|
||||
|
||||
if (aConfig.IsAudio()) {
|
||||
return aPEM->AsyncCreateEncoder(aConfig, aTaskQueue)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[config = aConfig](RefPtr<MediaDataEncoder>&& aEncoder) {
|
||||
RefPtr<MediaDataEncoder> decoder = std::move(aEncoder);
|
||||
return PlatformEncoderModule::CreateEncoderPromise::
|
||||
CreateAndResolve(decoder, __func__);
|
||||
},
|
||||
[](const MediaResult& aError) {
|
||||
return PlatformEncoderModule::CreateEncoderPromise::
|
||||
CreateAndReject(aError, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
if (!aConfig.IsVideo()) {
|
||||
return PlatformEncoderModule::CreateEncoderPromise::CreateAndReject(
|
||||
MediaResult(
|
||||
NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||
RESULT_DETAIL(
|
||||
"Encoder configuration error, expected audio or video.")),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return aPEM->AsyncCreateEncoder(aConfig, aTaskQueue);
|
||||
}
|
||||
|
||||
bool PEMFactory::Supports(const EncoderConfig& aConfig) const {
|
||||
RefPtr<PlatformEncoderModule> found;
|
||||
for (const auto& m : mCurrentPEMs) {
|
||||
if (m->Supports(aConfig)) {
|
||||
// TODO name
|
||||
LOG("Checking if %s supports codec %d: yes", m->GetName(),
|
||||
static_cast<int>(aConfig.mCodec));
|
||||
return true;
|
||||
}
|
||||
LOG("Checking if %s supports codec %d: no", m->GetName(),
|
||||
static_cast<int>(aConfig.mCodec));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PEMFactory::SupportsCodec(CodecType aCodec) const {
|
||||
for (const auto& m : mCurrentPEMs) {
|
||||
if (m->SupportsCodec(aCodec)) {
|
||||
// TODO name
|
||||
LOG("Checking if %s supports codec %d: yes", m->GetName(),
|
||||
static_cast<int>(aCodec));
|
||||
return true;
|
||||
}
|
||||
LOG("Checking if %s supports codec %d: no", m->GetName(),
|
||||
static_cast<int>(aCodec));
|
||||
}
|
||||
LOG("No PEM support %d", static_cast<int>(aCodec));
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<PlatformEncoderModule> PEMFactory::FindPEM(
|
||||
const TrackInfo& aTrackInfo) const {
|
||||
const EncoderConfig& aConfig) const {
|
||||
RefPtr<PlatformEncoderModule> found;
|
||||
for (auto m : mModules) {
|
||||
if (m->SupportsMimeType(aTrackInfo.mMimeType)) {
|
||||
for (const auto& m : mCurrentPEMs) {
|
||||
if (m->Supports(aConfig)) {
|
||||
found = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#undef LOGE
|
||||
#undef LOG
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
using PEMCreateEncoderPromise = PlatformEncoderModule::CreateEncoderPromise;
|
||||
|
||||
class PEMFactory final {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PEMFactory)
|
||||
|
|
@ -22,17 +24,28 @@ class PEMFactory final {
|
|||
// instance. It's expected that there will be multiple
|
||||
// PlatformEncoderModules alive at the same time.
|
||||
already_AddRefed<MediaDataEncoder> CreateEncoder(
|
||||
const CreateEncoderParams& aParams, const bool aHardwareNotAllowed);
|
||||
const EncoderConfig& aConfig, const RefPtr<TaskQueue>& aTaskQueue);
|
||||
|
||||
bool SupportsMimeType(const nsACString& aMimeType) const;
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise> CreateEncoderAsync(
|
||||
const EncoderConfig& aConfig, const RefPtr<TaskQueue>& aTaskQueue);
|
||||
|
||||
bool Supports(const EncoderConfig& aConfig) const;
|
||||
bool SupportsCodec(CodecType aCodec) const;
|
||||
|
||||
private:
|
||||
virtual ~PEMFactory() = default;
|
||||
// Returns the first PEM in our list supporting the mimetype.
|
||||
already_AddRefed<PlatformEncoderModule> FindPEM(
|
||||
const TrackInfo& aTrackInfo) const;
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise>
|
||||
CheckAndMaybeCreateEncoder(const EncoderConfig& aConfig, uint32_t aIndex,
|
||||
const RefPtr<TaskQueue>& aTaskQueue);
|
||||
|
||||
nsTArray<RefPtr<PlatformEncoderModule>> mModules;
|
||||
RefPtr<PlatformEncoderModule::CreateEncoderPromise> CreateEncoderWithPEM(
|
||||
PlatformEncoderModule* aPEM, const EncoderConfig& aConfig,
|
||||
const RefPtr<TaskQueue>& aTaskQueue);
|
||||
virtual ~PEMFactory() = default;
|
||||
// Returns the first PEM in our list supporting the codec.
|
||||
already_AddRefed<PlatformEncoderModule> FindPEM(
|
||||
const EncoderConfig& aConfig) const;
|
||||
|
||||
nsTArray<RefPtr<PlatformEncoderModule>> mCurrentPEMs;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
Loading…
Reference in a new issue