author | Wes Kocher <wkocher@mozilla.com> |
Wed, 29 Oct 2014 15:14:19 -0700 | |
changeset 213032 | 716fba2842f91ca1fe349491751639387eb5e6bb |
parent 213031 | 262e4847ad6cca40d7375e40a0d6ebe8b372e3d3 |
child 213033 | cb2065b39352c9bd94cf783b374ffd991dda45b6 |
push id | 27738 |
push user | cbook@mozilla.com |
push date | Thu, 30 Oct 2014 13:46:07 +0000 |
treeherder | mozilla-central@1aa1b23d799e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1089159 |
milestone | 36.0a1 |
backs out | 3629ea724086b7195adcb26e57c5244d6df9403c |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/media/fmp4/android/AndroidDecoderModule.cpp | file | annotate | diff | comparison | revisions | |
dom/media/fmp4/android/AndroidDecoderModule.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp +++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp @@ -64,17 +64,17 @@ public: return InitDecoder(mSurfaceTexture->JavaSurface()); } virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE { mp4_demuxer::AnnexB::ConvertSample(aSample, mConfig.annex_b); return MediaCodecDataDecoder::Input(aSample); } - virtual nsresult PostOutput(BufferInfo* aInfo, MediaFormat* aFormat, Microseconds aDuration) MOZ_OVERRIDE { + virtual nsresult PostOutput(BufferInfo* aInfo, Microseconds aDuration) MOZ_OVERRIDE { VideoInfo videoInfo; videoInfo.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height); bool isSync = false; if (MediaCodec::getBUFFER_FLAG_SYNC_FRAME() & aInfo->getFlags()) { isSync = true; } @@ -101,39 +101,44 @@ public: protected: layers::ImageContainer* mImageContainer; const mp4_demuxer::VideoDecoderConfig& mConfig; nsRefPtr<AndroidSurfaceTexture> mSurfaceTexture; }; class AudioDataDecoder : public MediaCodecDataDecoder { public: - AudioDataDecoder(const char* aMimeType, MediaFormat* aFormat, MediaDataDecoderCallback* aCallback) - : MediaCodecDataDecoder(MediaData::Type::AUDIO_SAMPLES, aMimeType, aFormat, aCallback) + AudioDataDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaFormat* aFormat, MediaDataDecoderCallback* aCallback) + : MediaCodecDataDecoder(MediaData::Type::AUDIO_SAMPLES, aConfig.mime_type, aFormat, aCallback) + , mConfig(aConfig) { + MOZ_ASSERT(mConfig.bits_per_sample == 16, "We only support 16-bit audio"); } - nsresult Output(BufferInfo* aInfo, void* aBuffer, MediaFormat* aFormat, Microseconds aDuration) { + nsresult Output(BufferInfo* aInfo, void* aBuffer, Microseconds aDuration) { // The output on Android is always 16-bit signed - uint32_t numChannels = aFormat->GetInteger(NS_LITERAL_STRING("channel-count")); - uint32_t sampleRate = aFormat->GetInteger(NS_LITERAL_STRING("sample-rate")); + uint32_t numChannels = mConfig.channel_count; uint32_t numFrames = (aInfo->getSize() / numChannels) / 2; AudioDataValue* audio = new AudioDataValue[aInfo->getSize()]; PodCopy(audio, static_cast<AudioDataValue*>(aBuffer), aInfo->getSize()); mCallback->Output(new AudioData(aInfo->getOffset(), aInfo->getPresentationTimeUs(), aDuration, numFrames, audio, numChannels, - sampleRate)); + mConfig.samples_per_second)); return NS_OK; } + +protected: + const mp4_demuxer::AudioDecoderConfig& mConfig; }; bool AndroidDecoderModule::SupportsAudioMimeType(const char* aMimeType) { JNIEnv* env = GetJNIForThread(); MediaCodec* decoder = CreateDecoder(env, aMimeType); bool supports = (decoder != nullptr); delete decoder; @@ -171,17 +176,16 @@ AndroidDecoderModule::CreateH264Decoder( return decoder.forget(); } already_AddRefed<MediaDataDecoder> AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, MediaTaskQueue* aAudioTaskQueue, MediaDataDecoderCallback* aCallback) { - MOZ_ASSERT(aCallback.bits_per_sample == 16, "We only handle 16-bit audio!"); nsAutoString mimeType; mimeType.AssignASCII(aConfig.mime_type); jobject jFormat = MediaFormat::CreateAudioFormat(mimeType, aConfig.samples_per_second, aConfig.channel_count); @@ -207,17 +211,17 @@ AndroidDecoderModule::CreateAudioDecoder env->DeleteLocalRef(buffer); } if (mimeType.EqualsLiteral("audio/mp4a-latm")) { format->SetInteger(NS_LITERAL_STRING("is-adts"), 1); } nsRefPtr<MediaDataDecoder> decoder = - new AudioDataDecoder(aConfig.mime_type, format, aCallback); + new AudioDataDecoder(aConfig, format, aCallback); return decoder.forget(); } nsresult AndroidDecoderModule::Shutdown() { @@ -293,18 +297,16 @@ nsresult MediaCodecDataDecoder::InitDeco void MediaCodecDataDecoder::DecoderLoop() { bool outputDone = false; JNIEnv* env = GetJNIForThread(); mp4_demuxer::MP4Sample* sample = nullptr; - nsAutoPtr<MediaFormat> outputFormat; - for (;;) { { MonitorAutoLock lock(mMonitor); while (!mStopping && !mDraining && mQueue.empty()) { if (mQueue.empty()) { // We could be waiting here forever if we don't signal that we need more input mCallback->InputExhausted(); } @@ -363,17 +365,17 @@ void MediaCodecDataDecoder::DecoderLoop( int outputStatus = mDecoder->DequeueOutputBuffer(bufferInfo.wrappedObject(), DECODER_TIMEOUT); if (outputStatus == MediaCodec::getINFO_TRY_AGAIN_LATER()) { // We might want to call mCallback->InputExhausted() here, but there seems to be // some possible bad interactions here with the threading } else if (outputStatus == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()) { ResetOutputBuffers(); } else if (outputStatus == MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED()) { - outputFormat = new MediaFormat(mDecoder->GetOutputFormat(), GetJNIForThread()); + // Don't care, we use SurfaceTexture for video } else if (outputStatus < 0) { printf_stderr("unknown error from decoder! %d\n", outputStatus); mCallback->Error(); } else { // We have a valid buffer index >= 0 here if (bufferInfo.getFlags() & MediaCodec::getBUFFER_FLAG_END_OF_STREAM()) { outputDone = true; } @@ -385,23 +387,23 @@ void MediaCodecDataDecoder::DecoderLoop( duration = mDurations.front(); mDurations.pop(); } jobject buffer = env->GetObjectArrayElement(mOutputBuffers, outputStatus); if (buffer) { // The buffer will be null on Android L if we are decoding to a Surface void* directBuffer = env->GetDirectBufferAddress(buffer); - Output(&bufferInfo, directBuffer, outputFormat, duration); + Output(&bufferInfo, directBuffer, duration); } // The Surface will be updated at this point (for video) mDecoder->ReleaseOutputBuffer(outputStatus, true); - PostOutput(&bufferInfo, outputFormat, duration); + PostOutput(&bufferInfo, duration); if (buffer) { env->DeleteLocalRef(buffer); } } } }
--- a/dom/media/fmp4/android/AndroidDecoderModule.h +++ b/dom/media/fmp4/android/AndroidDecoderModule.h @@ -89,18 +89,18 @@ protected: bool mDraining; bool mStopping; SampleQueue mQueue; std::queue<Microseconds> mDurations; virtual nsresult InitDecoder(jobject aSurface = nullptr); - virtual nsresult Output(mozilla::widget::android::BufferInfo* aInfo, void* aBuffer, mozilla::widget::android::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; } - virtual nsresult PostOutput(mozilla::widget::android::BufferInfo* aInfo, mozilla::widget::android::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; } + virtual nsresult Output(mozilla::widget::android::BufferInfo* aInfo, void* aBuffer, Microseconds aDuration) { return NS_OK; } + virtual nsresult PostOutput(mozilla::widget::android::BufferInfo* aInfo, Microseconds aDuration) { return NS_OK; } void ResetInputBuffers(); void ResetOutputBuffers(); void DecoderLoop(); virtual void ClearQueue(); };