Skip to content

Commit 3888a39

Browse files
committed
Bug 1891082 - Implement CodecChangeMonitor for AAC in MediaChangeMonitor r=media-playback-reviewers,padenot
This patch implements a `CodecChangeMonitor` specifically for *AAC* format, which will later be integrated into the `MediaChangeMonitor`. The `CheckForChange` function within `CodecChangeMonitor` is designed to detect changes in the data format and signal `MediaChangeMonitor` to re-create and re-initialize the underlying decoder accordingly. When the data stream format changes from *ADTS* to *AAC*, the `CodecChangeMonitor` will add an AAC-specific configuration that is missing in *ADTS* for proper decoder configuration. Conversely, when the format switches from *AAC* to *ADTS*, it will reconfigure the decoder without the AAC-specific configuration. Depends on D219147 Differential Revision: https://phabricator.services.mozilla.com/D220505 UltraBlame original commit: 85611c424c137426a9d6b5709fc4796436e1380a
1 parent 77b9397 commit 3888a39

File tree

1 file changed

+75
-3
lines changed

1 file changed

+75
-3
lines changed

dom/media/platforms/wrappers/MediaChangeMonitor.cpp

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "MediaChangeMonitor.h"
88

9+
#include "Adts.h"
910
#include "AnnexB.h"
1011
#include "H264.h"
1112
#include "H265.h"
@@ -588,6 +589,73 @@ class AV1ChangeMonitor : public MediaChangeMonitor::CodecChangeMonitor {
588589
};
589590
#endif
590591

592+
class AACCodecChangeMonitor : public MediaChangeMonitor::CodecChangeMonitor {
593+
public:
594+
explicit AACCodecChangeMonitor(const AudioInfo& aInfo)
595+
: mCurrentConfig(aInfo), mIsADTS(IsADTS(aInfo)) {}
596+
597+
bool CanBeInstantiated() const override { return true; }
598+
599+
MediaResult CheckForChange(MediaRawData* aSample) override {
600+
bool isADTS =
601+
ADTS::FrameHeader::MatchesSync(Span{aSample->Data(), aSample->Size()});
602+
if (isADTS != mIsADTS) {
603+
if (mIsADTS) {
604+
if (!MakeAACSpecificConfig()) {
605+
LOG("Failed to make AAC specific config");
606+
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR);
607+
}
608+
LOG("Reconfiguring decoder adts -> raw aac, with maked AAC specific "
609+
"config: %zu bytes",
610+
mCurrentConfig.mCodecSpecificConfig
611+
.as<AudioCodecSpecificBinaryBlob>()
612+
.mBinaryBlob->Length());
613+
} else {
614+
LOG("Reconfiguring decoder raw aac -> adts");
615+
616+
mCurrentConfig.mCodecSpecificConfig =
617+
AudioCodecSpecificVariant{NoCodecSpecificData{}};
618+
}
619+
620+
mIsADTS = isADTS;
621+
return MediaResult(NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER);
622+
}
623+
return NS_OK;
624+
}
625+
626+
const TrackInfo& Config() const override { return mCurrentConfig; }
627+
628+
MediaResult PrepareSample(MediaDataDecoder::ConversionRequired aConversion,
629+
MediaRawData* aSample,
630+
bool aNeedKeyFrame) override {
631+
return NS_OK;
632+
}
633+
634+
private:
635+
static bool IsADTS(const AudioInfo& aInfo) {
636+
return !aInfo.mCodecSpecificConfig.is<AacCodecSpecificData>() &&
637+
!aInfo.mCodecSpecificConfig.is<AudioCodecSpecificBinaryBlob>();
638+
}
639+
640+
bool MakeAACSpecificConfig() {
641+
MOZ_ASSERT(IsADTS(mCurrentConfig));
642+
643+
const uint8_t aacObjectType =
644+
mCurrentConfig.mProfile ? mCurrentConfig.mProfile : 2;
645+
auto r = ADTS::MakeSpecificConfig(aacObjectType, mCurrentConfig.mRate,
646+
mCurrentConfig.mChannels);
647+
if (r.isErr()) {
648+
return false;
649+
}
650+
mCurrentConfig.mCodecSpecificConfig =
651+
AudioCodecSpecificVariant{AudioCodecSpecificBinaryBlob{r.unwrap()}};
652+
return true;
653+
}
654+
655+
AudioInfo mCurrentConfig;
656+
bool mIsADTS;
657+
};
658+
591659
MediaChangeMonitor::MediaChangeMonitor(
592660
PDMFactory* aPDMFactory,
593661
UniquePtr<CodecChangeMonitor>&& aCodecChangeMonitor,
@@ -601,6 +669,7 @@ MediaChangeMonitor::MediaChangeMonitor(
601669

602670
RefPtr<PlatformDecoderModule::CreateDecoderPromise> MediaChangeMonitor::Create(
603671
PDMFactory* aPDMFactory, const CreateDecoderParams& aParams) {
672+
LOG("MediaChangeMonitor::Create, params = %s", aParams.ToString().get());
604673
UniquePtr<CodecChangeMonitor> changeMonitor;
605674
const VideoInfo& currentConfig = aParams.VideoConfig();
606675
if (VPXDecoder::IsVPX(currentConfig.mMimeType)) {
@@ -623,6 +692,7 @@ RefPtr<PlatformDecoderModule::CreateDecoderPromise> MediaChangeMonitor::Create(
623692

624693

625694
const CreateDecoderParams updatedParams{changeMonitor->Config(), aParams};
695+
LOG("updated params = %s", updatedParams.ToString().get());
626696

627697
RefPtr<MediaChangeMonitor> instance = new MediaChangeMonitor(
628698
aPDMFactory, std::move(changeMonitor), nullptr, updatedParams);
@@ -851,10 +921,12 @@ void MediaChangeMonitor::SetSeekThreshold(const media::TimeUnit& aTime) {
851921
RefPtr<MediaChangeMonitor::CreateDecoderPromise>
852922
MediaChangeMonitor::CreateDecoder() {
853923
mCurrentConfig = *mChangeMonitor->Config().GetAsVideoInfo();
924+
CreateDecoderParams currentParams = {mCurrentConfig, mParams};
925+
currentParams.mWrappers -= media::Wrapper::MediaChangeMonitor;
926+
LOG("MediaChangeMonitor::CreateDecoder, current params = %s",
927+
currentParams.ToString().get());
854928
RefPtr<CreateDecoderPromise> p =
855-
mPDMFactory
856-
->CreateDecoder(
857-
{mCurrentConfig, mParams, CreateDecoderParams::NoWrapper(true)})
929+
mPDMFactory->CreateDecoder(currentParams)
858930
->Then(
859931
GetCurrentSerialEventTarget(), __func__,
860932
[self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) {

0 commit comments

Comments
 (0)