nsresult WMFMediaDataDecoder::Shutdown() { MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown); if (mTaskQueue) { nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown); mTaskQueue->Dispatch(runnable.forget()); } else { ProcessShutdown(); } mIsShutDown = true; return NS_OK; }
void AppleATDecoder::ProcessFlush() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); mQueuedSamples.Clear(); if (mConverter) { OSStatus rv = AudioConverterReset(mConverter); if (rv) { LOG("Error %d resetting AudioConverter", rv); } } if (mErrored) { mParsedFramesForAACMagicCookie = 0; mMagicCookie.Clear(); ProcessShutdown(); mErrored = false; } }
RefPtr<MediaDataDecoder::FlushPromise> AppleATDecoder::ProcessFlush() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); mQueuedSamples.Clear(); mDecodedSamples.Clear(); if (mConverter) { OSStatus rv = AudioConverterReset(mConverter); if (rv) { LOG("Error %d resetting AudioConverter", static_cast<int>(rv)); } } if (mErrored) { mParsedFramesForAACMagicCookie = 0; mMagicCookie.Clear(); ProcessShutdown(); mErrored = false; } return FlushPromise::CreateAndResolve(true, __func__); }
MediaResult AppleATDecoder::SetupDecoder(MediaRawData* aSample) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); static const uint32_t MAX_FRAMES = 2; if (mFormatID == kAudioFormatMPEG4AAC && mConfig.mExtendedProfile == 2 && mParsedFramesForAACMagicCookie < MAX_FRAMES) { // 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()) { // nothing found yet, will try again later mParsedFramesForAACMagicCookie++; return NS_ERROR_NOT_INITIALIZED; } // An error occurred, fallback to using default stream description } LOG("Initializing Apple AudioToolbox decoder"); nsTArray<uint8_t>& magicCookie = mMagicCookie.Length() ? mMagicCookie : *mConfig.mExtraData; AudioStreamBasicDescription inputFormat; PodZero(&inputFormat); MediaResult rv = GetInputAudioDescription(inputFormat, magicCookie); if (NS_FAILED(rv)) { return rv; } // Fill in the output format manually. PodZero(&mOutputFormat); mOutputFormat.mFormatID = kAudioFormatLinearPCM; mOutputFormat.mSampleRate = inputFormat.mSampleRate; mOutputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame; #if defined(MOZ_SAMPLE_TYPE_FLOAT32) mOutputFormat.mBitsPerChannel = 32; mOutputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | 0; #elif defined(MOZ_SAMPLE_TYPE_S16) mOutputFormat.mBitsPerChannel = 16; mOutputFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | 0; #else # error Unknown audio sample type #endif // Set up the decoder so it gives us one sample per frame mOutputFormat.mFramesPerPacket = 1; mOutputFormat.mBytesPerPacket = mOutputFormat.mBytesPerFrame = mOutputFormat.mChannelsPerFrame * mOutputFormat.mBitsPerChannel / 8; OSStatus status = AudioConverterNew(&inputFormat, &mOutputFormat, &mConverter); if (status) { LOG("Error %d constructing AudioConverter", int(status)); mConverter = nullptr; return MediaResult( NS_ERROR_FAILURE, RESULT_DETAIL("Error constructing AudioConverter:%d", int32_t(status))); } if (magicCookie.Length() && mFormatID == kAudioFormatMPEG4AAC) { status = AudioConverterSetProperty(mConverter, kAudioConverterDecompressionMagicCookie, magicCookie.Length(), magicCookie.Elements()); if (status) { LOG("Error setting AudioConverter AAC cookie:%d", int32_t(status)); ProcessShutdown(); return MediaResult( NS_ERROR_FAILURE, RESULT_DETAIL("Error setting AudioConverter AAC cookie:%d", int32_t(status))); } } if (NS_FAILED(SetupChannelLayout())) { NS_WARNING("Couldn't retrieve channel layout, will use default layout"); } return NS_OK; }