summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/apple
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/platforms/apple')
-rw-r--r--dom/media/platforms/apple/AppleATDecoder.cpp90
-rw-r--r--dom/media/platforms/apple/AppleATDecoder.h5
-rw-r--r--dom/media/platforms/apple/AppleDecoderModule.cpp7
-rw-r--r--dom/media/platforms/apple/AppleVTDecoder.cpp10
4 files changed, 79 insertions, 33 deletions
diff --git a/dom/media/platforms/apple/AppleATDecoder.cpp b/dom/media/platforms/apple/AppleATDecoder.cpp
index ed64b62d60..3065ac0c27 100644
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -14,6 +14,9 @@
#include "mozilla/SyncRunnable.h"
#include "mozilla/UniquePtr.h"
#include "nsTArray.h"
+#include "ADTSDemuxer.h"
+
+#include <array>
#define LOG(...) DDMOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, __VA_ARGS__)
#define LOGEX(_this, ...) \
@@ -62,6 +65,7 @@ AppleATDecoder::~AppleATDecoder() {
RefPtr<MediaDataDecoder::InitPromise> AppleATDecoder::Init() {
if (!mFormatID) {
+ LOG("AppleATDecoder::Init failure: unknown format ID");
return InitPromise::CreateAndReject(
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("Non recognised format")),
@@ -85,6 +89,7 @@ RefPtr<MediaDataDecoder::FlushPromise> AppleATDecoder::Flush() {
}
}
if (mErrored) {
+ LOG("Flush error");
mParsedFramesForAACMagicCookie = 0;
mMagicCookie.Clear();
ProcessShutdown();
@@ -188,18 +193,28 @@ RefPtr<MediaDataDecoder::DecodePromise> AppleATDecoder::Decode(
MediaResult rv = NS_OK;
if (!mConverter) {
+ LOG("Lazily initing the decoder");
rv = SetupDecoder(aSample);
if (rv != NS_OK && rv != NS_ERROR_NOT_INITIALIZED) {
+ LOG("Decoder not initialized");
return DecodePromise::CreateAndReject(rv, __func__);
}
}
+ if (mIsADTS) {
+ bool rv = ADTS::StripHeader(aSample);
+ if (!rv) {
+ LOG("Stripping the ADTS header in AppleATDecoder failed");
+ }
+ }
+
mQueuedSamples.AppendElement(aSample);
if (rv == NS_OK) {
for (size_t i = 0; i < mQueuedSamples.Length(); i++) {
rv = DecodeSample(mQueuedSamples[i]);
if (NS_FAILED(rv)) {
+ LOG("Decoding error");
mErrored = true;
return DecodePromise::CreateAndReject(rv, __func__);
}
@@ -277,7 +292,7 @@ MediaResult AppleATDecoder::DecodeSample(MediaRawData* aSample) {
}
size_t numFrames = outputData.Length() / channels;
- int rate = mOutputFormat.mSampleRate;
+ int rate = AssertedCast<int>(mOutputFormat.mSampleRate);
media::TimeUnit duration(numFrames, rate);
if (!duration.IsValid()) {
NS_WARNING("Invalid count of accumulated audio samples");
@@ -340,8 +355,8 @@ MediaResult AppleATDecoder::GetInputAudioDescription(
aDesc.mChannelsPerFrame = mConfig.mChannels;
aDesc.mSampleRate = mConfig.mRate;
UInt32 inputFormatSize = sizeof(aDesc);
- OSStatus rv = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL,
- &inputFormatSize, &aDesc);
+ OSStatus rv = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0,
+ nullptr, &inputFormatSize, &aDesc);
if (NS_WARN_IF(rv)) {
return MediaResult(
NS_ERROR_FAILURE,
@@ -419,7 +434,7 @@ nsresult AppleATDecoder::SetupChannelLayout() {
UInt32 propertySize;
UInt32 size;
OSStatus status = AudioConverterGetPropertyInfo(
- mConverter, kAudioConverterOutputChannelLayout, &propertySize, NULL);
+ mConverter, kAudioConverterOutputChannelLayout, &propertySize, nullptr);
if (status || !propertySize) {
LOG("Couldn't get channel layout property (%s)", FourCC2Str(status));
return NS_ERROR_FAILURE;
@@ -504,15 +519,36 @@ MediaResult AppleATDecoder::SetupDecoder(MediaRawData* aSample) {
MOZ_ASSERT(mThread->IsOnCurrentThread());
static const uint32_t MAX_FRAMES = 2;
+ bool isADTS =
+ ADTS::FrameHeader::MatchesSync(Span{aSample->Data(), aSample->Size()});
+
+ if (isADTS) {
+ ADTS::FrameParser parser;
+ if (!parser.Parse(0, aSample->Data(), aSample->Data() + aSample->Size())) {
+ LOG("ADTS frame parsing error");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ AudioCodecSpecificBinaryBlob blob;
+ ADTS::InitAudioSpecificConfig(parser.FirstFrame(), blob.mBinaryBlob);
+ mConfig.mCodecSpecificConfig = AudioCodecSpecificVariant{std::move(blob)};
+ mConfig.mProfile = mConfig.mExtendedProfile =
+ parser.FirstFrame().Header().mObjectType;
+ mIsADTS = true;
+ }
+
if (mFormatID == kAudioFormatMPEG4AAC && mConfig.mExtendedProfile == 2 &&
mParsedFramesForAACMagicCookie < MAX_FRAMES) {
+ LOG("Attempting to get implicit AAC magic cookie");
// Check for implicit SBR signalling if stream is AAC-LC
// This will provide us with an updated magic cookie for use with
// GetInputAudioDescription.
if (NS_SUCCEEDED(GetImplicitAACMagicCookie(aSample)) &&
- !mMagicCookie.Length()) {
+ !mMagicCookie.Length() && !isADTS) {
// nothing found yet, will try again later
+ LOG("Getting implicit AAC magic cookie failed");
mParsedFramesForAACMagicCookie++;
+ LOG("Not initialized -- need magic cookie");
return NS_ERROR_NOT_INITIALIZED;
}
// An error occurred, fallback to using default stream description
@@ -538,6 +574,7 @@ MediaResult AppleATDecoder::SetupDecoder(MediaRawData* aSample) {
MediaResult rv = GetInputAudioDescription(inputFormat, magicCookie);
if (NS_FAILED(rv)) {
+ LOG("GetInputAudioDescription failure");
return rv;
}
// Fill in the output format manually.
@@ -617,28 +654,41 @@ static void _SampleCallback(void* aSBR, UInt32 aNumBytes, UInt32 aNumPackets,
const void* aData,
AudioStreamPacketDescription* aPackets) {}
-nsresult AppleATDecoder::GetImplicitAACMagicCookie(
- const MediaRawData* aSample) {
+nsresult AppleATDecoder::GetImplicitAACMagicCookie(MediaRawData* aSample) {
MOZ_ASSERT(mThread->IsOnCurrentThread());
- // Prepend ADTS header to AAC audio.
- RefPtr<MediaRawData> adtssample(aSample->Clone());
- if (!adtssample) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- int8_t frequency_index = Adts::GetFrequencyIndex(mConfig.mRate);
+ bool isADTS =
+ ADTS::FrameHeader::MatchesSync(Span{aSample->Data(), aSample->Size()});
- bool rv = Adts::ConvertSample(mConfig.mChannels, frequency_index,
- mConfig.mProfile, adtssample);
- if (!rv) {
- NS_WARNING("Failed to apply ADTS header");
- return NS_ERROR_FAILURE;
+ RefPtr<MediaRawData> adtssample = aSample;
+
+ if (!isADTS) {
+ // Prepend ADTS header to AAC audio.
+ adtssample = aSample->Clone();
+ if (!adtssample) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ auto frequency_index = ADTS::GetFrequencyIndex(mConfig.mRate);
+
+ if (frequency_index.isErr()) {
+ LOG("%d isn't a valid rate for AAC", mConfig.mRate);
+ return NS_ERROR_FAILURE;
+ }
+
+ // Arbitrarily pick main profile if not specified
+ int profile = mConfig.mProfile ? mConfig.mProfile : 1;
+ bool rv = ADTS::ConvertSample(mConfig.mChannels, frequency_index.unwrap(),
+ profile, adtssample);
+ if (!rv) {
+ LOG("Failed to apply ADTS header");
+ return NS_ERROR_FAILURE;
+ }
}
if (!mStream) {
OSStatus rv = AudioFileStreamOpen(this, _MetadataCallback, _SampleCallback,
kAudioFileAAC_ADTSType, &mStream);
if (rv) {
- NS_WARNING("Couldn't open AudioFileStream");
+ LOG("Couldn't open AudioFileStream");
return NS_ERROR_FAILURE;
}
}
@@ -646,7 +696,7 @@ nsresult AppleATDecoder::GetImplicitAACMagicCookie(
OSStatus status = AudioFileStreamParseBytes(
mStream, adtssample->Size(), adtssample->Data(), 0 /* discontinuity */);
if (status) {
- NS_WARNING("Couldn't parse sample");
+ LOG("Couldn't parse sample");
}
if (status || mFileStreamError || mMagicCookie.Length()) {
diff --git a/dom/media/platforms/apple/AppleATDecoder.h b/dom/media/platforms/apple/AppleATDecoder.h
index d7aba2aacb..392b39993f 100644
--- a/dom/media/platforms/apple/AppleATDecoder.h
+++ b/dom/media/platforms/apple/AppleATDecoder.h
@@ -38,7 +38,7 @@ class AppleATDecoder final : public MediaDataDecoder,
nsCString GetCodecName() const override;
// Callbacks also need access to the config.
- const AudioInfo mConfig;
+ AudioInfo mConfig;
// Use to extract magic cookie for HE-AAC detection.
nsTArray<uint8_t> mMagicCookie;
@@ -67,11 +67,12 @@ class AppleATDecoder final : public MediaDataDecoder,
// Setup AudioConverter once all information required has been gathered.
// Will return NS_ERROR_NOT_INITIALIZED if more data is required.
MediaResult SetupDecoder(MediaRawData* aSample);
- nsresult GetImplicitAACMagicCookie(const MediaRawData* aSample);
+ nsresult GetImplicitAACMagicCookie(MediaRawData* aSample);
nsresult SetupChannelLayout();
uint32_t mParsedFramesForAACMagicCookie;
uint32_t mEncoderDelay = 0;
uint64_t mTotalMediaFrames = 0;
+ bool mIsADTS = false;
bool mErrored;
};
diff --git a/dom/media/platforms/apple/AppleDecoderModule.cpp b/dom/media/platforms/apple/AppleDecoderModule.cpp
index 520685fff6..c54593a495 100644
--- a/dom/media/platforms/apple/AppleDecoderModule.cpp
+++ b/dom/media/platforms/apple/AppleDecoderModule.cpp
@@ -124,8 +124,7 @@ DecodeSupportSet AppleDecoderModule::Supports(
case MediaCodec::VP8:
[[fallthrough]];
case MediaCodec::VP9:
- if (StaticPrefs::media_ffvpx_enabled() &&
- StaticPrefs::media_rdd_vpx_enabled() &&
+ if (StaticPrefs::media_rdd_vpx_enabled() &&
StaticPrefs::media_utility_ffvpx_enabled()) {
dss += DecodeSupport::SoftwareDecode;
}
@@ -233,6 +232,7 @@ bool AppleDecoderModule::CanCreateHWDecoder(MediaCodec aCodec) {
/* static */
bool AppleDecoderModule::RegisterSupplementalVP9Decoder() {
+#ifdef XP_MACOSX
static bool sRegisterIfAvailable = []() {
if (__builtin_available(macos 11.0, *)) {
VTRegisterSupplementalVideoDecoderIfAvailable(kCMVideoCodecType_VP9);
@@ -241,6 +241,9 @@ bool AppleDecoderModule::RegisterSupplementalVP9Decoder() {
return false;
}();
return sRegisterIfAvailable;
+#else // iOS
+ return false;
+#endif
}
/* static */
diff --git a/dom/media/platforms/apple/AppleVTDecoder.cpp b/dom/media/platforms/apple/AppleVTDecoder.cpp
index aae9c1fc9b..ae34c2d142 100644
--- a/dom/media/platforms/apple/AppleVTDecoder.cpp
+++ b/dom/media/platforms/apple/AppleVTDecoder.cpp
@@ -7,7 +7,7 @@
#include "AppleVTDecoder.h"
#include <CoreVideo/CVPixelBufferIOSurface.h>
-#include <IOSurface/IOSurface.h>
+#include <IOSurface/IOSurfaceRef.h>
#include <limits>
#include "AppleDecoderModule.h"
@@ -486,7 +486,6 @@ void AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
} else {
-#ifndef MOZ_WIDGET_UIKIT
// Set pixel buffer properties on aImage before we extract its surface.
// This ensures that we can use defined enums to set values instead
// of later setting magic CFSTR values on the surface itself.
@@ -535,9 +534,6 @@ void AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
info.mDisplay, aFrameRef.byte_offset, aFrameRef.composition_timestamp,
aFrameRef.duration, image.forget(), aFrameRef.is_sync_point,
aFrameRef.decode_timestamp);
-#else
- MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
-#endif
}
if (!data) {
@@ -719,7 +715,6 @@ CFDictionaryRef AppleVTDecoder::CreateOutputConfiguration() {
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
-#ifndef MOZ_WIDGET_UIKIT
// Output format type:
bool is10Bit = (gfx::BitDepthForColorDepth(mColorDepth) == 10);
@@ -754,9 +749,6 @@ CFDictionaryRef AppleVTDecoder::CreateOutputConfiguration() {
return CFDictionaryCreate(
kCFAllocatorDefault, outputKeys, outputValues, ArrayLength(outputKeys),
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-#else
- MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
-#endif
}
} // namespace mozilla