Bug 1089159 - Correctly use MediaCodec's audio output format r=cpearce

--HG--
extra : rebase_source : 2b3b3a43e54cdcdac87e303a2705e8be7c60d3dd
This commit is contained in:
James Willcox 2014-10-29 18:40:06 -05:00
parent 22b3d5b9fe
commit 9fda622507
2 changed files with 16 additions and 18 deletions

View File

@ -69,7 +69,7 @@ public:
return MediaCodecDataDecoder::Input(aSample);
}
virtual nsresult PostOutput(BufferInfo* aInfo, Microseconds aDuration) MOZ_OVERRIDE {
virtual nsresult PostOutput(BufferInfo* aInfo, MediaFormat* aFormat, Microseconds aDuration) MOZ_OVERRIDE {
VideoInfo videoInfo;
videoInfo.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height);
@ -106,18 +106,16 @@ protected:
class AudioDataDecoder : public MediaCodecDataDecoder {
public:
AudioDataDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaFormat* aFormat, MediaDataDecoderCallback* aCallback)
: MediaCodecDataDecoder(MediaData::Type::AUDIO_SAMPLES, aConfig.mime_type, aFormat, aCallback)
, mConfig(aConfig)
AudioDataDecoder(const char* aMimeType, MediaFormat* aFormat, MediaDataDecoderCallback* aCallback)
: MediaCodecDataDecoder(MediaData::Type::AUDIO_SAMPLES, aMimeType, aFormat, aCallback)
{
MOZ_ASSERT(mConfig.bits_per_sample == 16, "We only support 16-bit audio");
}
nsresult Output(BufferInfo* aInfo, void* aBuffer, Microseconds aDuration) {
nsresult Output(BufferInfo* aInfo, void* aBuffer, MediaFormat* aFormat, Microseconds aDuration) {
// The output on Android is always 16-bit signed
uint32_t numChannels = mConfig.channel_count;
uint32_t numChannels = aFormat->GetInteger(NS_LITERAL_STRING("channel-count"));
uint32_t sampleRate = aFormat->GetInteger(NS_LITERAL_STRING("sample-rate"));
uint32_t numFrames = (aInfo->getSize() / numChannels) / 2;
AudioDataValue* audio = new AudioDataValue[aInfo->getSize()];
@ -128,12 +126,9 @@ public:
numFrames,
audio,
numChannels,
mConfig.samples_per_second));
sampleRate));
return NS_OK;
}
protected:
const mp4_demuxer::AudioDecoderConfig& mConfig;
};
@ -181,6 +176,7 @@ AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig&
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
MOZ_ASSERT(aConfig.bits_per_sample == 16, "We only handle 16-bit audio!");
nsAutoString mimeType;
mimeType.AssignASCII(aConfig.mime_type);
@ -216,7 +212,7 @@ AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig&
}
nsRefPtr<MediaDataDecoder> decoder =
new AudioDataDecoder(aConfig, format, aCallback);
new AudioDataDecoder(aConfig.mime_type, format, aCallback);
return decoder.forget();
@ -302,6 +298,8 @@ void MediaCodecDataDecoder::DecoderLoop()
JNIEnv* env = GetJNIForThread();
mp4_demuxer::MP4Sample* sample = nullptr;
nsAutoPtr<MediaFormat> outputFormat;
for (;;) {
{
MonitorAutoLock lock(mMonitor);
@ -370,7 +368,7 @@ void MediaCodecDataDecoder::DecoderLoop()
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()) {
ResetOutputBuffers();
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED()) {
// Don't care, we use SurfaceTexture for video
outputFormat = new MediaFormat(mDecoder->GetOutputFormat(), GetJNIForThread());
} else if (outputStatus < 0) {
printf_stderr("unknown error from decoder! %d\n", outputStatus);
mCallback->Error();
@ -392,13 +390,13 @@ void MediaCodecDataDecoder::DecoderLoop()
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, duration);
Output(&bufferInfo, directBuffer, outputFormat, duration);
}
// The Surface will be updated at this point (for video)
mDecoder->ReleaseOutputBuffer(outputStatus, true);
PostOutput(&bufferInfo, duration);
PostOutput(&bufferInfo, outputFormat, duration);
if (buffer) {
env->DeleteLocalRef(buffer);

View File

@ -94,8 +94,8 @@ protected:
virtual nsresult InitDecoder(jobject aSurface = nullptr);
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; }
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; }
void ResetInputBuffers();
void ResetOutputBuffers();