Skip to content

Commit e6fa040

Browse files
committed
Bug 1891082 - Enable decoder reconfiguration in DecoderAgent for AAC/ADTS data through MediaChangeMonitor r=media-playback-reviewers,padenot
This patch enhances `DecoderAgent` by enabling it to reconfigure the underlying decoder when processing *AAC/ADTS* data via `MediaChangeMonitor`. In cases where the `description` field is absent in the `AudioDecoderConfig` for `mp4a.*` (*AAC*) codec, the data stream is assumed to be in *ADTS* format. However, some websites provide raw AAC data under these circumstances, leading to decoding failure since the underlying decoder requires AAC-specific configuration. This patch resolves the issue by allowing the underling decoder to be reconfigured - recreated and reinitialized - through `MediaChangeMonitor` whenever an AAV format change is detected. This process mirros the handling of video format changes, such as when H264 data format changes between AnnexB and AVCC. With this change, `DecoderAgent` simply cues the `PDMFactory` to create a `MediaChangeMonitor` that wraps the underlying decoder, similar to the approach used for video decoders, ensuring correct handling of both AAC and ADTS formats without altering other components. Depends on D220505 Differential Revision: https://phabricator.services.mozilla.com/D220506 UltraBlame original commit: 02c9b1fb72c80c7ad2e73174d2c45e0eead0b26d
1 parent 3888a39 commit e6fa040

File tree

5 files changed

+132
-59
lines changed

5 files changed

+132
-59
lines changed

dom/media/platforms/PDMFactory.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,19 @@ PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
409409
}
410410

411411
if (config.IsAudio()) {
412+
if (MP4Decoder::IsAAC(config.mMimeType) && !aParams.mUseNullDecoder.mUse &&
413+
aParams.mWrappers.contains(media::Wrapper::MediaChangeMonitor)) {
414+
415+
return MediaChangeMonitor::Create(this, aParams);
416+
}
412417
RefPtr<PlatformDecoderModule::CreateDecoderPromise> p;
413418
p = aPDM->AsyncCreateDecoder(aParams)->Then(
414419
GetCurrentSerialEventTarget(), __func__,
415420
[params = CreateDecoderParamsForAsync(aParams)](
416421
RefPtr<MediaDataDecoder>&& aDecoder) {
417422
RefPtr<MediaDataDecoder> decoder = std::move(aDecoder);
418-
if (!params.mNoWrapper.mDontUseWrapper) {
419-
decoder =
420-
new AudioTrimmer(decoder.forget(), CreateDecoderParams(params));
423+
if (params.mWrappers.contains(media::Wrapper::AudioTrimmer)) {
424+
decoder = new AudioTrimmer(decoder.forget());
421425
}
422426
return PlatformDecoderModule::CreateDecoderPromise::CreateAndResolve(
423427
decoder, __func__);
@@ -444,7 +448,8 @@ PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
444448
#endif
445449
VPXDecoder::IsVPX(config.mMimeType) ||
446450
MP4Decoder::IsHEVC(config.mMimeType)) &&
447-
!aParams.mUseNullDecoder.mUse && !aParams.mNoWrapper.mDontUseWrapper) {
451+
!aParams.mUseNullDecoder.mUse &&
452+
aParams.mWrappers.contains(media::Wrapper::MediaChangeMonitor)) {
448453
return MediaChangeMonitor::Create(this, aParams);
449454
}
450455
return aPDM->AsyncCreateDecoder(aParams);

dom/media/platforms/PlatformDecoderModule.h

Lines changed: 94 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,36 @@ static LazyLogModule sPDMLog("PlatformDecoderModule");
4343

4444
namespace media {
4545

46-
enum class Option {
47-
Default,
48-
LowLatency,
49-
HardwareDecoderNotAllowed,
50-
FullH264Parsing,
51-
ErrorIfNoInitializationData,
52-
53-
54-
55-
DefaultPlaybackDeviceMono,
56-
57-
KeepOriginalPts,
58-
59-
60-
SENTINEL
61-
};
46+
template <typename T>
47+
static nsCString EnumSetToString(const EnumSet<T>& aSet) {
48+
nsCString str;
49+
for (const auto e : aSet) {
50+
if (!str.IsEmpty()) {
51+
str.AppendLiteral("|");
52+
}
53+
str.AppendPrintf("%s", EnumValueToString(e));
54+
}
55+
if (str.IsEmpty()) {
56+
str.AppendLiteral("Empty");
57+
}
58+
return str;
59+
}
60+
61+
MOZ_DEFINE_ENUM_CLASS_WITH_TOSTRING(
62+
Option,
63+
(Default, LowLatency, HardwareDecoderNotAllowed, FullH264Parsing,
64+
ErrorIfNoInitializationData,
65+
66+
67+
68+
DefaultPlaybackDeviceMono,
69+
70+
KeepOriginalPts,
71+
72+
73+
SENTINEL
74+
));
75+
6276
using OptionSet = EnumSet<Option>;
6377

6478
struct UseNullDecoder {
@@ -68,11 +82,22 @@ struct UseNullDecoder {
6882
};
6983

7084

71-
struct NoWrapper {
72-
NoWrapper() = default;
73-
explicit NoWrapper(bool aDontUseWrapper) : mDontUseWrapper(aDontUseWrapper) {}
74-
bool mDontUseWrapper = false;
75-
};
85+
MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING(Wrapper, uint8_t,
86+
(AudioTrimmer,
87+
MediaChangeMonitor));
88+
using WrapperSet = EnumSet<Wrapper>;
89+
static WrapperSet GetDefaultWrapperSet(const TrackInfo& aInfo) {
90+
91+
92+
WrapperSet set;
93+
if (aInfo.IsVideo()) {
94+
set += Wrapper::MediaChangeMonitor;
95+
}
96+
if (aInfo.IsAudio()) {
97+
set += Wrapper::AudioTrimmer;
98+
}
99+
return set;
100+
}
76101

77102
struct VideoFrameRate {
78103
VideoFrameRate() = default;
@@ -104,7 +129,7 @@ struct CreateDecoderParamsForAsync {
104129
const RefPtr<layers::KnowsCompositor> mKnowsCompositor;
105130
const RefPtr<GMPCrashHelper> mCrashHelper;
106131
const media::UseNullDecoder mUseNullDecoder;
107-
const media::NoWrapper mNoWrapper;
132+
const media::WrapperSet mWrappers;
108133
const TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
109134
std::function<MediaEventProducer<TrackInfo::TrackType>*()>
110135
mOnWaitingForKeyEvent;
@@ -118,14 +143,15 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
118143
using Option = media::Option;
119144
using OptionSet = media::OptionSet;
120145
using UseNullDecoder = media::UseNullDecoder;
121-
using NoWrapper = media::NoWrapper;
146+
using WrapperSet = media::WrapperSet;
122147
using VideoFrameRate = media::VideoFrameRate;
123148
enum class EncryptedCustomIdent : bool {
124149
False,
125150
True,
126151
};
127152

128-
explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {}
153+
explicit CreateDecoderParams(const TrackInfo& aConfig)
154+
: mConfig(aConfig), mWrappers(media::GetDefaultWrapperSet(aConfig)) {}
129155
CreateDecoderParams(const CreateDecoderParams& aParams) = default;
130156

131157
MOZ_IMPLICIT CreateDecoderParams(const CreateDecoderParamsForAsync& aParams)
@@ -134,7 +160,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
134160
mKnowsCompositor(aParams.mKnowsCompositor),
135161
mCrashHelper(aParams.mCrashHelper),
136162
mUseNullDecoder(aParams.mUseNullDecoder),
137-
mNoWrapper(aParams.mNoWrapper),
163+
mWrappers(aParams.mWrappers),
138164
mType(aParams.mType),
139165
mOnWaitingForKeyEvent(aParams.mOnWaitingForKeyEvent),
140166
mOptions(aParams.mOptions),
@@ -144,7 +170,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
144170

145171
template <typename T1, typename... Ts>
146172
CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
147-
: mConfig(aConfig) {
173+
: mConfig(aConfig), mWrappers(media::GetDefaultWrapperSet(aConfig)) {
148174
Set(std::forward<T1>(a1), std::forward<Ts>(args)...);
149175
}
150176

@@ -164,13 +190,44 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
164190
return *mConfig.GetAsAudioInfo();
165191
}
166192

193+
bool IsVideo() const { return mConfig.IsVideo(); }
194+
195+
bool IsAudio() const { return mConfig.IsAudio(); }
196+
167197
layers::LayersBackend GetLayersBackend() const {
168198
if (mKnowsCompositor) {
169199
return mKnowsCompositor->GetCompositorBackendType();
170200
}
171201
return layers::LayersBackend::LAYERS_NONE;
172202
}
173203

204+
nsCString ToString() const {
205+
nsPrintfCString str("CreateDecoderParams @ %p: ", this);
206+
str.AppendPrintf("mConfig = %s", mConfig.ToString().get());
207+
str.AppendPrintf(", mImageContainer = %p", mImageContainer);
208+
str.AppendPrintf(", mError = %s",
209+
mError ? mError->Description().get() : "null");
210+
str.AppendPrintf(", mKnowsCompositor = %p", mKnowsCompositor);
211+
str.AppendPrintf(", mCrashHelper = %p", mCrashHelper);
212+
str.AppendPrintf(", mUseNullDecoder = %s",
213+
mUseNullDecoder.mUse ? "yes" : "no");
214+
str.AppendPrintf(", mWrappers = %s", EnumSetToString(mWrappers).get());
215+
str.AppendPrintf(", mType = %d", static_cast<int32_t>(mType));
216+
str.AppendPrintf(", mOnWaitingForKeyEvent = %s",
217+
mOnWaitingForKeyEvent ? "yes" : "no");
218+
str.AppendPrintf(", mOptions = %s", EnumSetToString(mOptions).get());
219+
str.AppendPrintf(", mRate = %f", mRate.mValue);
220+
str.AppendPrintf(
221+
", mMediaEngineId = %s",
222+
mMediaEngineId ? std::to_string(*mMediaEngineId).c_str() : "None");
223+
str.AppendPrintf(", mTrackingId = %s",
224+
mTrackingId ? mTrackingId->ToString().get() : "None");
225+
str.AppendPrintf(
226+
", mEncryptedCustomIdent = %s",
227+
mEncryptedCustomIdent == EncryptedCustomIdent::True ? "true" : "false");
228+
return std::move(str);
229+
}
230+
174231

175232

176233

@@ -180,7 +237,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
180237
layers::KnowsCompositor* mKnowsCompositor = nullptr;
181238
GMPCrashHelper* mCrashHelper = nullptr;
182239
media::UseNullDecoder mUseNullDecoder;
183-
media::NoWrapper mNoWrapper;
240+
WrapperSet mWrappers;
184241
TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
185242
std::function<MediaEventProducer<TrackInfo::TrackType>*()>
186243
mOnWaitingForKeyEvent;
@@ -189,7 +246,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
189246

190247
Maybe<uint64_t> mMediaEngineId;
191248
Maybe<TrackingId> mTrackingId;
192-
EncryptedCustomIdent mEncryptedCustomIdent;
249+
EncryptedCustomIdent mEncryptedCustomIdent = EncryptedCustomIdent::False;
193250

194251
private:
195252
void Set(layers::ImageContainer* aImageContainer) {
@@ -200,7 +257,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
200257
void Set(UseNullDecoder aUseNullDecoder) {
201258
mUseNullDecoder = aUseNullDecoder;
202259
}
203-
void Set(NoWrapper aNoWrapper) { mNoWrapper = aNoWrapper; }
260+
void Set(const WrapperSet& aWrappers) { mWrappers = aWrappers; }
204261
void Set(const OptionSet& aOptions) { mOptions = aOptions; }
205262
void Set(VideoFrameRate aRate) { mRate = aRate; }
206263
void Set(layers::KnowsCompositor* aKnowsCompositor) {
@@ -232,7 +289,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
232289
mKnowsCompositor = aParams.mKnowsCompositor;
233290
mCrashHelper = aParams.mCrashHelper;
234291
mUseNullDecoder = aParams.mUseNullDecoder;
235-
mNoWrapper = aParams.mNoWrapper;
292+
mWrappers = aParams.mWrappers;
236293
mType = aParams.mType;
237294
mOnWaitingForKeyEvent = aParams.mOnWaitingForKeyEvent;
238295
mOptions = aParams.mOptions;
@@ -251,24 +308,25 @@ struct MOZ_STACK_CLASS SupportDecoderParams final {
251308
using Option = media::Option;
252309
using OptionSet = media::OptionSet;
253310
using UseNullDecoder = media::UseNullDecoder;
254-
using NoWrapper = media::NoWrapper;
311+
using WrapperSet = media::WrapperSet;
255312
using VideoFrameRate = media::VideoFrameRate;
256313

257-
explicit SupportDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {}
314+
explicit SupportDecoderParams(const TrackInfo& aConfig)
315+
: mConfig(aConfig), mWrappers(media::GetDefaultWrapperSet(aConfig)) {}
258316

259317
explicit SupportDecoderParams(const CreateDecoderParams& aParams)
260318
: mConfig(aParams.mConfig),
261319
mError(aParams.mError),
262320
mKnowsCompositor(aParams.mKnowsCompositor),
263321
mUseNullDecoder(aParams.mUseNullDecoder),
264-
mNoWrapper(aParams.mNoWrapper),
322+
mWrappers(aParams.mWrappers),
265323
mOptions(aParams.mOptions),
266324
mRate(aParams.mRate),
267325
mMediaEngineId(aParams.mMediaEngineId) {}
268326

269327
template <typename T1, typename... Ts>
270328
SupportDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
271-
: mConfig(aConfig) {
329+
: mConfig(aConfig), mWrappers(media::GetDefaultWrapperSet(aConfig)) {
272330
Set(std::forward<T1>(a1), std::forward<Ts>(args)...);
273331
}
274332

@@ -279,7 +337,7 @@ struct MOZ_STACK_CLASS SupportDecoderParams final {
279337
MediaResult* mError = nullptr;
280338
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
281339
UseNullDecoder mUseNullDecoder;
282-
NoWrapper mNoWrapper;
340+
WrapperSet mWrappers;
283341
OptionSet mOptions = OptionSet(Option::Default);
284342
VideoFrameRate mRate;
285343
Maybe<uint64_t> mMediaEngineId;
@@ -292,7 +350,7 @@ struct MOZ_STACK_CLASS SupportDecoderParams final {
292350
void Set(media::UseNullDecoder aUseNullDecoder) {
293351
mUseNullDecoder = aUseNullDecoder;
294352
}
295-
void Set(media::NoWrapper aNoWrapper) { mNoWrapper = aNoWrapper; }
353+
void Set(const WrapperSet& aWrappers) { mWrappers = aWrappers; }
296354
void Set(const media::OptionSet& aOptions) { mOptions = aOptions; }
297355
void Set(media::VideoFrameRate aRate) { mRate = aRate; }
298356
void Set(layers::KnowsCompositor* aKnowsCompositor) {

dom/media/platforms/wrappers/MediaChangeMonitor.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ MediaChangeMonitor::MediaChangeMonitor(
662662
MediaDataDecoder* aDecoder, const CreateDecoderParams& aParams)
663663
: mChangeMonitor(std::move(aCodecChangeMonitor)),
664664
mPDMFactory(aPDMFactory),
665-
mCurrentConfig(aParams.VideoConfig()),
665+
mCurrentConfig(aParams.mConfig.Clone()),
666666
mDecoder(aDecoder),
667667
mParams(aParams) {}
668668

@@ -671,20 +671,25 @@ RefPtr<PlatformDecoderModule::CreateDecoderPromise> MediaChangeMonitor::Create(
671671
PDMFactory* aPDMFactory, const CreateDecoderParams& aParams) {
672672
LOG("MediaChangeMonitor::Create, params = %s", aParams.ToString().get());
673673
UniquePtr<CodecChangeMonitor> changeMonitor;
674-
const VideoInfo& currentConfig = aParams.VideoConfig();
675-
if (VPXDecoder::IsVPX(currentConfig.mMimeType)) {
676-
changeMonitor = MakeUnique<VPXChangeMonitor>(currentConfig);
674+
if (aParams.IsVideo()) {
675+
const VideoInfo& config = aParams.VideoConfig();
676+
if (VPXDecoder::IsVPX(config.mMimeType)) {
677+
changeMonitor = MakeUnique<VPXChangeMonitor>(config);
677678
#ifdef MOZ_AV1
678-
} else if (AOMDecoder::IsAV1(currentConfig.mMimeType)) {
679-
changeMonitor = MakeUnique<AV1ChangeMonitor>(currentConfig);
679+
} else if (AOMDecoder::IsAV1(config.mMimeType)) {
680+
changeMonitor = MakeUnique<AV1ChangeMonitor>(config);
680681
#endif
681-
} else if (MP4Decoder::IsHEVC(currentConfig.mMimeType)) {
682-
changeMonitor = MakeUnique<HEVCChangeMonitor>(currentConfig);
682+
} else if (MP4Decoder::IsHEVC(config.mMimeType)) {
683+
changeMonitor = MakeUnique<HEVCChangeMonitor>(config);
684+
} else {
685+
MOZ_ASSERT(MP4Decoder::IsH264(config.mMimeType));
686+
changeMonitor = MakeUnique<H264ChangeMonitor>(
687+
config, aParams.mOptions.contains(
688+
CreateDecoderParams::Option::FullH264Parsing));
689+
}
683690
} else {
684-
MOZ_ASSERT(MP4Decoder::IsH264(currentConfig.mMimeType));
685-
changeMonitor = MakeUnique<H264ChangeMonitor>(
686-
currentConfig, aParams.mOptions.contains(
687-
CreateDecoderParams::Option::FullH264Parsing));
691+
MOZ_ASSERT(MP4Decoder::IsAAC(aParams.AudioConfig().mMimeType));
692+
changeMonitor = MakeUnique<AACCodecChangeMonitor>(aParams.AudioConfig());
688693
}
689694

690695

@@ -920,8 +925,8 @@ void MediaChangeMonitor::SetSeekThreshold(const media::TimeUnit& aTime) {
920925

921926
RefPtr<MediaChangeMonitor::CreateDecoderPromise>
922927
MediaChangeMonitor::CreateDecoder() {
923-
mCurrentConfig = *mChangeMonitor->Config().GetAsVideoInfo();
924-
CreateDecoderParams currentParams = {mCurrentConfig, mParams};
928+
mCurrentConfig = mChangeMonitor->Config().Clone();
929+
CreateDecoderParams currentParams = {*mCurrentConfig, mParams};
925930
currentParams.mWrappers -= media::Wrapper::MediaChangeMonitor;
926931
LOG("MediaChangeMonitor::CreateDecoder, current params = %s",
927932
currentParams.ToString().get());

dom/media/platforms/wrappers/MediaChangeMonitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class MediaChangeMonitor final
127127

128128
UniquePtr<CodecChangeMonitor> mChangeMonitor;
129129
RefPtr<PDMFactory> mPDMFactory;
130-
VideoInfo mCurrentConfig;
130+
UniquePtr<TrackInfo> mCurrentConfig;
131131
nsCOMPtr<nsISerialEventTarget> mThread;
132132
RefPtr<MediaDataDecoder> mDecoder;
133133
MozPromiseRequestHolder<CreateDecoderPromise> mDecoderRequest;

dom/media/webcodecs/DecoderAgent.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "DecoderAgent.h"
88

99
#include "ImageContainer.h"
10+
#include "MP4Decoder.h"
1011
#include "MediaDataDecoderProxy.h"
1112
#include "PDMFactory.h"
1213
#include "VideoUtils.h"
@@ -106,6 +107,10 @@ RefPtr<DecoderAgent::ConfigurePromise> DecoderAgent::Configure(
106107
params.mOptions += CreateDecoderParams::Option::LowLatency;
107108
}
108109

110+
if (MP4Decoder::IsAAC(mInfo->mMimeType)) {
111+
params.mWrappers += media::Wrapper::MediaChangeMonitor;
112+
}
113+
109114
if (StaticPrefs::media_test_null_decoder_creation_failure()) {
110115
params.mUseNullDecoder = CreateDecoderParams::UseNullDecoder(true);
111116
}
@@ -114,10 +119,10 @@ RefPtr<DecoderAgent::ConfigurePromise> DecoderAgent::Configure(
114119

115120
params.mOptions += CreateDecoderParams::Option::KeepOriginalPts;
116121

117-
LOG("DecoderAgent #%d (%p) is creating a decoder - PreferSW: %s, "
118-
"low-latency: %s",
119-
mId, this, aPreferSoftwareDecoder ? "yes" : "no",
120-
aLowLatency ? "yes" : "no");
122+
LOG("DecoderAgent #%d (%p) is creating a decoder (mime: %s) - PreferSW: %s, "
123+
"low-latency: %s, create-decoder-params: %s",
124+
mId, this, mInfo->mMimeType.get(), aPreferSoftwareDecoder ? "yes" : "no",
125+
aLowLatency ? "yes" : "no", params.ToString().get());
121126

122127
RefPtr<ConfigurePromise> p = mConfigurePromise.Ensure(__func__);
123128

0 commit comments

Comments
 (0)