Bug 1749046 - Add Opus-specific configuration options. r=chunmin,webidl,smaug

Differential Revision: https://phabricator.services.mozilla.com/D199540
This commit is contained in:
Paul Adenot 2024-03-27 14:16:30 +00:00
parent 40c99f5805
commit c473a3ec48
3 changed files with 52 additions and 3 deletions

View file

@ -78,6 +78,29 @@ AudioEncoderConfigInternal::AudioEncoderConfigInternal(
OptionalToMaybe(aConfig.mNumberOfChannels), OptionalToMaybe(aConfig.mNumberOfChannels),
OptionalToMaybe(aConfig.mBitrate), aConfig.mBitrateMode) { OptionalToMaybe(aConfig.mBitrate), aConfig.mBitrateMode) {
DebugOnly<nsCString> errorMessage; DebugOnly<nsCString> errorMessage;
if (aConfig.mCodec.EqualsLiteral("opus") && aConfig.mOpus.WasPassed()) {
// All values are in range at this point, the config is known valid.
OpusSpecific specific;
if (aConfig.mOpus.Value().mComplexity.WasPassed()) {
specific.mComplexity = aConfig.mOpus.Value().mComplexity.Value();
} else {
// https://w3c.github.io/webcodecs/opus_codec_registration.html#dom-opusencoderconfig-complexity
// If no value is specificied, the default value is platform-specific:
// User Agents SHOULD set a default of 5 for mobile platforms, and a
// default of 9 for all other platforms.
if (IsOnAndroid()) {
specific.mComplexity = 5;
} else {
specific.mComplexity = 9;
}
}
specific.mApplication = OpusSpecific::Application::Unspecified;
specific.mFrameDuration = aConfig.mOpus.Value().mFrameDuration;
specific.mPacketLossPerc = aConfig.mOpus.Value().mPacketlossperc;
specific.mUseDTX = aConfig.mOpus.Value().mUsedtx;
specific.mUseInBandFEC = aConfig.mOpus.Value().mUseinbandfec;
mSpecific.emplace(specific);
}
MOZ_ASSERT(AudioEncoderTraits::Validate(aConfig, errorMessage)); MOZ_ASSERT(AudioEncoderTraits::Validate(aConfig, errorMessage));
} }
@ -87,6 +110,11 @@ AudioEncoderConfigInternal::AudioEncoderConfigInternal(
aConfig.mNumberOfChannels, aConfig.mBitrate, aConfig.mNumberOfChannels, aConfig.mBitrate,
aConfig.mBitrateMode) {} aConfig.mBitrateMode) {}
void AudioEncoderConfigInternal::SetSpecific(
const EncoderConfig::CodecSpecific& aSpecific) {
mSpecific.emplace(aSpecific);
}
/* /*
* The followings are helpers for AudioEncoder methods * The followings are helpers for AudioEncoder methods
*/ */
@ -187,6 +215,8 @@ EncoderConfig AudioEncoderConfigInternal::ToEncoderConfig() const {
Maybe<EncoderConfig::CodecSpecific> specific; Maybe<EncoderConfig::CodecSpecific> specific;
if (mCodec.EqualsLiteral("opus")) { if (mCodec.EqualsLiteral("opus")) {
type = CodecType::Opus; type = CodecType::Opus;
MOZ_ASSERT(mSpecific.isNothing() || mSpecific->is<OpusSpecific>());
specific = mSpecific;
} else if (mCodec.EqualsLiteral("vorbis")) { } else if (mCodec.EqualsLiteral("vorbis")) {
type = CodecType::Vorbis; type = CodecType::Vorbis;
} else if (mCodec.EqualsLiteral("flac")) { } else if (mCodec.EqualsLiteral("flac")) {
@ -268,7 +298,8 @@ bool AudioEncoderTraits::Validate(const AudioEncoderConfig& aConfig,
return false; return false;
} }
if (aConfig.mBitrate.WasPassed() && aConfig.mBitrate.Value() > std::numeric_limits<int>::max()) { if (aConfig.mBitrate.WasPassed() &&
aConfig.mBitrate.Value() > std::numeric_limits<int>::max()) {
aErrorMessage.AppendPrintf("Invalid config: bitrate value too large"); aErrorMessage.AppendPrintf("Invalid config: bitrate value too large");
return false; return false;
} }

View file

@ -17,7 +17,6 @@
#include "nsStringFwd.h" #include "nsStringFwd.h"
#include "nsTLiteralString.h" #include "nsTLiteralString.h"
#include "VideoDecoder.h" #include "VideoDecoder.h"
#include "PlatformEncoderModule.h"
namespace mozilla { namespace mozilla {
@ -33,6 +32,8 @@ class AudioEncoderConfigInternal {
explicit AudioEncoderConfigInternal( explicit AudioEncoderConfigInternal(
const AudioEncoderConfigInternal& aConfig); const AudioEncoderConfigInternal& aConfig);
void SetSpecific(const EncoderConfig::CodecSpecific& aSpecific);
nsString ToString() const; nsString ToString() const;
bool Equals(const AudioEncoderConfigInternal& aOther) const; bool Equals(const AudioEncoderConfigInternal& aOther) const;
@ -40,7 +41,6 @@ class AudioEncoderConfigInternal {
// Returns an EncoderConfig struct with as many filled members as // Returns an EncoderConfig struct with as many filled members as
// possible. // possible.
// TODO: handle codec specific things
EncoderConfig ToEncoderConfig() const; EncoderConfig ToEncoderConfig() const;
already_AddRefed<WebCodecsConfigurationChangeList> Diff( already_AddRefed<WebCodecsConfigurationChangeList> Diff(
@ -51,6 +51,7 @@ class AudioEncoderConfigInternal {
Maybe<uint32_t> mNumberOfChannels; Maybe<uint32_t> mNumberOfChannels;
Maybe<uint32_t> mBitrate; Maybe<uint32_t> mBitrate;
BitrateMode mBitrateMode; BitrateMode mBitrateMode;
Maybe<EncoderConfig::CodecSpecific> mSpecific;
private: private:
AudioEncoderConfigInternal(const nsAString& aCodec, AudioEncoderConfigInternal(const nsAString& aCodec,

View file

@ -23,6 +23,23 @@ dictionary AudioEncoderConfig {
[EnforceRange] unsigned long numberOfChannels; [EnforceRange] unsigned long numberOfChannels;
[EnforceRange] unsigned long long bitrate; [EnforceRange] unsigned long long bitrate;
BitrateMode bitrateMode = "variable"; BitrateMode bitrateMode = "variable";
OpusEncoderConfig opus;
};
// Opus specific configuration options:
// https://w3c.github.io/webcodecs/opus_codec_registration.html
enum OpusBitstreamFormat {
"opus",
"ogg",
};
dictionary OpusEncoderConfig {
OpusBitstreamFormat format = "opus";
[EnforceRange] unsigned long long frameDuration = 20000;
[EnforceRange] unsigned long complexity;
[EnforceRange] unsigned long packetlossperc = 0;
boolean useinbandfec = false;
boolean usedtx = false;
}; };
[Exposed=(Window,DedicatedWorker), SecureContext, Pref="dom.media.webcodecs.enabled"] [Exposed=(Window,DedicatedWorker), SecureContext, Pref="dom.media.webcodecs.enabled"]