# HG changeset patch # User Jean-Yves Avenard # Date 1521215821 -3600 # Fri Mar 16 16:57:01 2018 +0100 # Node ID 6531087bc2062b7dfde6d0352d99ce2ad278a950 # Parent 938c300a46ca9c337a541a047c04b4be92e65a89 Bug 1444479 - P7. Allow Apple AudioToolbox decoder handle more than 8 channels. r=padenot Apple layout standard has a 1:1 equivalence with the WAVE standard. As such, any streams under 18 channels, properly defining a channel layout, should play on all platform. Otherwise, as Opus and Vorbis, the result will be platform dependent. MozReview-Commit-ID: ID6b9u2UNQr diff --git a/dom/media/platforms/apple/AppleATDecoder.cpp b/dom/media/platforms/apple/AppleATDecoder.cpp --- a/dom/media/platforms/apple/AppleATDecoder.cpp +++ b/dom/media/platforms/apple/AppleATDecoder.cpp @@ -1,23 +1,24 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "AppleATDecoder.h" +#include "Adts.h" #include "AppleUtils.h" #include "MP4Decoder.h" -#include "Adts.h" #include "MediaInfo.h" +#include "VideoUtils.h" #include "mozilla/Logging.h" #include "mozilla/SyncRunnable.h" #include "mozilla/UniquePtr.h" -#include "VideoUtils.h" +#include "nsTArray.h" #define LOG(...) DDMOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, __VA_ARGS__) #define LOGEX(_this, ...) \ DDMOZ_LOGEX(_this, sPDMLog, mozilla::LogLevel::Debug, __VA_ARGS__) #define FourCC2Str(n) ((char[5]){(char)(n >> 24), (char)(n >> 16), (char)(n >> 8), (char)(n), 0}) namespace mozilla { @@ -308,40 +309,37 @@ AppleATDecoder::DecodeSample(MediaRawDat duration.ToSeconds()); #endif AudioSampleBuffer data(outputData.Elements(), outputData.Length()); if (!data.Data()) { return NS_ERROR_OUT_OF_MEMORY; } if (mChannelLayout && !mAudioConverter) { - AudioConfig in(*mChannelLayout, rate); + AudioConfig in(*mChannelLayout, channels, rate); AudioConfig out(AudioConfig::ChannelLayout::SMPTEDefault(*mChannelLayout), - rate); - if (!in.IsValid() || !out.IsValid()) { - return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, - RESULT_DETAIL("Invalid audio config")); - } + channels, rate); mAudioConverter = MakeUnique(in, out); } - if (mAudioConverter) { + if (mAudioConverter && mChannelLayout && mChannelLayout->IsValid()) { MOZ_ASSERT(mAudioConverter->CanWorkInPlace()); data = mAudioConverter->Process(Move(data)); } RefPtr audio = new AudioData(aSample->mOffset, aSample->mTime, duration, numFrames, data.Forget(), channels, rate, - mChannelLayout ? mChannelLayout->Map() - : AudioConfig::ChannelLayout::UNKNOWN_MAP); + mChannelLayout && mChannelLayout->IsValid() + ? mChannelLayout->Map() + : AudioConfig::ChannelLayout::UNKNOWN_MAP); mDecodedSamples.AppendElement(Move(audio)); return NS_OK; } MediaResult AppleATDecoder::GetInputAudioDescription(AudioStreamBasicDescription& aDesc, const nsTArray& aExtraData) { @@ -526,31 +524,31 @@ AppleATDecoder::SetupChannelLayout() FourCC2Str(property), FourCC2Str(status)); return NS_ERROR_FAILURE; } // We have retrieved the channel layout from the tag or bitmap. // We can now directly use the channel descriptions. layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; } - if (layout->mNumberChannelDescriptions > MAX_AUDIO_CHANNELS || - layout->mNumberChannelDescriptions != mOutputFormat.mChannelsPerFrame) { - LOG("Nonsensical channel layout or not matching the original channel number"); + if (layout->mNumberChannelDescriptions != mOutputFormat.mChannelsPerFrame) { + LOG("Not matching the original channel number"); return NS_ERROR_FAILURE; } - AudioConfig::Channel channels[MAX_AUDIO_CHANNELS]; + AutoTArray channels; + channels.SetLength(layout->mNumberChannelDescriptions); for (uint32_t i = 0; i < layout->mNumberChannelDescriptions; i++) { AudioChannelLabel id = layout->mChannelDescriptions[i].mChannelLabel; AudioConfig::Channel channel = ConvertChannelLabel(id); channels[i] = channel; } mChannelLayout = MakeUnique(mOutputFormat.mChannelsPerFrame, - channels); + channels.Elements()); return NS_OK; } MediaResult AppleATDecoder::SetupDecoder(MediaRawData* aSample) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); static const uint32_t MAX_FRAMES = 2;