|
6 | 6 |
|
7 | 7 | #include "MediaChangeMonitor.h"
|
8 | 8 |
|
| 9 | +#include "Adts.h" |
9 | 10 | #include "AnnexB.h"
|
10 | 11 | #include "H264.h"
|
11 | 12 | #include "H265.h"
|
@@ -588,6 +589,73 @@ class AV1ChangeMonitor : public MediaChangeMonitor::CodecChangeMonitor {
|
588 | 589 | };
|
589 | 590 | #endif
|
590 | 591 |
|
| 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 | + // Remove AAC specific config to configure a ADTS decoder. |
| 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 | + // If profile is not set, default to AAC-LC |
| 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 | + |
591 | 659 | MediaChangeMonitor::MediaChangeMonitor(
|
592 | 660 | PDMFactory* aPDMFactory,
|
593 | 661 | UniquePtr<CodecChangeMonitor>&& aCodecChangeMonitor,
|
|
0 commit comments