summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2014-10-07 23:14:32 -0700
committerSteve Kondik <shade@chemlab.org>2014-10-08 17:56:27 -0700
commitbf1690beb04508b079cb255a13c8fb0b9e098e29 (patch)
tree335cc8201adf597c93618dfbeec89c846593754e
parent0ea7bfd6ae3dd587a4981969edf74361fc469a4d (diff)
downloadframeworks_av-bf1690beb04508b079cb255a13c8fb0b9e098e29.tar.gz
frameworks_av-bf1690beb04508b079cb255a13c8fb0b9e098e29.tar.bz2
frameworks_av-bf1690beb04508b079cb255a13c8fb0b9e098e29.zip
stagefright: More high-resolution audio support
* Clean up the "error driven" fallback code we had before and reconfigure components if the output bit width needs to change (a2dp/usb fallback). * Decode various formats (AC3/DTS/EAC3) which output floating point samples using FFMPEG, which will output 24-bit PCM for us. Change-Id: I94f5fa59f5f737be8969df4c5ad4295c45cb8657
-rw-r--r--include/media/stagefright/ExtendedCodec.h6
-rw-r--r--media/libstagefright/AudioPlayer.cpp10
-rw-r--r--media/libstagefright/AwesomePlayer.cpp3
-rw-r--r--media/libstagefright/ExtendedCodec.cpp41
-rw-r--r--media/libstagefright/OMXCodec.cpp50
-rw-r--r--media/libstagefright/Utils.cpp16
6 files changed, 97 insertions, 29 deletions
diff --git a/include/media/stagefright/ExtendedCodec.h b/include/media/stagefright/ExtendedCodec.h
index eaca72c859..5ec73a78ac 100644
--- a/include/media/stagefright/ExtendedCodec.h
+++ b/include/media/stagefright/ExtendedCodec.h
@@ -147,6 +147,12 @@ struct ExtendedCodec {
static bool isSourcePauseRequired(const char *componentName);
+#if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
+ static status_t updatePcmOutputFormat(const sp<MetaData> &meta,
+ sp<IOMX> OMXhandle, IOMX::node_id nodeID,
+ const char* componentName);
+#endif
+
private:
static const char* getMsgKey(int key );
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 6b8399bdf6..0a00161924 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -182,13 +182,13 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
if (mapMimeToAudioFormat(audioFormat, mime) != OK) {
ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime);
audioFormat = AUDIO_FORMAT_INVALID;
- } else {
+ } else if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat)) {
#if defined(QCOM_HARDWARE) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
// Override audio format for PCM offload
- if (audioFormat == AUDIO_FORMAT_PCM_24_BIT || bitWidth == 24) {
- ALOGI("24-bit PCM offload enabled");
+ if (bitWidth >= 24) {
+ ALOGD("24-bit PCM offload enabled format=%d", audioFormat);
audioFormat = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD;
- } else if (audioFormat == AUDIO_FORMAT_PCM_16_BIT) {
+ } else {
audioFormat = AUDIO_FORMAT_PCM_16_BIT_OFFLOAD;
}
#endif
@@ -225,7 +225,7 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0);
offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0);
#if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
- offloadInfo.bit_width = bitWidth;
+ offloadInfo.bit_width = bitWidth >= 24 ? 24 : bitWidth;
#endif
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 7fc4512add..cc152d8385 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1931,6 +1931,7 @@ status_t AwesomePlayer::initAudioDecoder() {
mAudioSource = mAudioTrack;
#ifndef QCOM_DIRECTTRACK
} else {
+ mOmxSource->getFormat()->setInt32(kKeySampleBits, 16);
mAudioSource = mOmxSource;
#endif
}
@@ -1942,7 +1943,7 @@ status_t AwesomePlayer::initAudioDecoder() {
mAudioTrack->getFormat()->findInt32(kKeySampleBits, &bitsPerSample);
if (!mOffloadAudio && mAudioSource != NULL) {
- ALOGI("Could not offload audio decode, try pcm offload");
+ ALOGI("Could not offload audio decode, try pcm offload (%d-bit)", bitsPerSample);
sp<MetaData> format = mAudioSource->getFormat();
if (durationUs >= 0) {
format->setInt64(kKeyDuration, durationUs);
diff --git a/media/libstagefright/ExtendedCodec.cpp b/media/libstagefright/ExtendedCodec.cpp
index 9a048d73e0..bb87490bae 100644
--- a/media/libstagefright/ExtendedCodec.cpp
+++ b/media/libstagefright/ExtendedCodec.cpp
@@ -323,7 +323,7 @@ status_t ExtendedCodec::setAudioFormat(
const sp<AMessage> &msg, const char* mime, sp<IOMX> OMXhandle,
IOMX::node_id nodeID, bool isEncoder ) {
ALOGV("setAudioFormat called");
- status_t err = OK;
+ status_t err = ERROR_UNSUPPORTED;
if ((!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mime)) ||
(!strcasecmp(MEDIA_MIMETYPE_AUDIO_EAC3, mime))){
@@ -333,16 +333,19 @@ status_t ExtendedCodec::setAudioFormat(
//setAC3Format(numChannels, sampleRate, OMXhandle, nodeID);
CHECK(msg->findInt32("channel-count", &numChannels));
CHECK(msg->findInt32("sample-rate", &sampleRate));
+ err = OK;
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_EVRC, mime)) {
int32_t numChannels, sampleRate;
CHECK(msg->findInt32("channel-count", &numChannels));
CHECK(msg->findInt32("sample-rate", &sampleRate));
setEVRCFormat(numChannels, sampleRate, OMXhandle, nodeID, isEncoder );
+ err = OK;
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_QCELP, mime)) {
int32_t numChannels, sampleRate;
CHECK(msg->findInt32("channel-count", &numChannels));
CHECK(msg->findInt32("sample-rate", &sampleRate));
setQCELPFormat(numChannels, sampleRate, OMXhandle, nodeID, isEncoder);
+ err = OK;
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_WMA, mime)) {
err = setWMAFormat(msg, OMXhandle, nodeID, isEncoder);
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS, mime)) {
@@ -418,8 +421,10 @@ status_t ExtendedCodec::setSupportedRole(
"video_decoder.divx", NULL },
{ MEDIA_MIMETYPE_VIDEO_WMV,
"video_decoder.vc1", NULL },
+#if 0 // handled by FFMPEG
{ MEDIA_MIMETYPE_AUDIO_AC3,
"audio_decoder.ac3", NULL },
+#endif
{ MEDIA_MIMETYPE_AUDIO_WMA,
"audio_decoder.wma" , NULL },
{ MEDIA_MIMETYPE_VIDEO_HEVC,
@@ -1399,3 +1404,37 @@ namespace android {
} //namespace android
#endif //ENABLE_AV_ENHANCEMENTS
+
+#if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
+namespace android {
+
+ status_t ExtendedCodec::updatePcmOutputFormat(
+ const sp<MetaData> &meta, sp<IOMX> OMXhandle, IOMX::node_id nodeID,
+ const char* componentName) {
+
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+ int32_t bits_per_sample = 16;
+ int32_t sample_rate;
+ int32_t channels;
+ status_t err = OK;
+
+ CHECK(meta->findInt32(kKeyChannelCount, &channels));
+ CHECK(meta->findInt32(kKeySampleRate, &sample_rate));
+
+ if (!meta->findInt32(kKeySampleBits, &bits_per_sample)) {
+ ALOGD("Bits per sample not specified, using default 16");
+ }
+ ALOGD("Update output bit width = %d", bits_per_sample);
+
+ InitOMXParams(&param);
+ param.nPortIndex = kPortIndexOutput;
+ param.nChannels = channels;
+ param.nSamplingRate = sample_rate;
+ param.nBitPerSample = bits_per_sample;
+
+ return OMXhandle->setParameter(nodeID, OMX_IndexParamAudioPcm,
+ &param, sizeof(param));
+ }
+
+} // namespace android
+#endif
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 0ac0d2a02e..8646fbe492 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -850,12 +850,19 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
CODEC_LOGE("setMP2Format() failed (err = %d)", err);
return err;
}
- } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mMIME)) {
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mMIME) ||
+ !strcasecmp(MEDIA_MIMETYPE_AUDIO_EAC3, mMIME)) {
status_t err = setAC3Format(meta);
if (err != OK) {
CODEC_LOGE("setAC3Format() failed (err = %d)", err);
return err;
}
+#ifdef ENABLE_AV_ENHANCEMENTS
+ // FFMPEG will convert floating point to 24-bit PCM
+ if (ExtendedUtils::isHiresAudioEnabled()) {
+ meta->setInt32(kKeySampleBits, 24);
+ }
+#endif
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_APE, mMIME)) {
status_t err = setAPEFormat(meta);
if (err != OK) {
@@ -882,16 +889,18 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
}
#ifdef QCOM_HARDWARE
} else {
- if (mIsEncoder && !mIsVideo) {
- int32_t numChannels, sampleRate;
- CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
- CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
- setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
- }
- status_t err = ExtendedCodec::setAudioFormat(
- meta, mMIME, mOMX, mNode, mIsEncoder);
- if(OK != err) {
- return err;
+ if (!mIsVideo) {
+ if (mIsEncoder) {
+ int32_t numChannels, sampleRate;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+ CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+ setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
+ }
+ status_t err = ExtendedCodec::setAudioFormat(
+ meta, mMIME, mOMX, mNode, mIsEncoder);
+ if(OK != err) {
+ return err;
+ }
}
#endif
}
@@ -2097,6 +2106,13 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
}
}
+#if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
+ if (!mIsVideo && portIndex == kPortIndexOutput &&
+ !strncmp(mComponentName, "OMX.ffmpeg.", 11)) {
+ ExtendedCodec::updatePcmOutputFormat(mOutputFormat, mOMX, mNode, NULL);
+ }
+#endif
+
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = portIndex;
@@ -4514,7 +4530,7 @@ status_t OMXCodec::setFLACFormat(const sp<MetaData> &meta)
{
int32_t numChannels = 0;
int32_t sampleRate = 0;
- int32_t bitsPerSample = 0;
+ int32_t bitsPerSample = 16;
OMX_AUDIO_PARAM_FLACTYPE param;
if (mIsEncoder) {
@@ -4524,10 +4540,12 @@ status_t OMXCodec::setFLACFormat(const sp<MetaData> &meta)
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
- CHECK(meta->findInt32(kKeySampleBits, &bitsPerSample));
+ if (!meta->findInt32(kKeySampleBits, &bitsPerSample)) {
+ CODEC_LOGV("BitsPerSample not set, using default");
+ }
- CODEC_LOGV("Channels: %d, SampleRate: %d",
- numChannels, sampleRate);
+ CODEC_LOGV("Channels: %d, SampleRate: %d, BitsPerSample: %d",
+ numChannels, sampleRate, bitsPerSample);
InitOMXParams(&param);
param.nPortIndex = kPortIndexInput;
@@ -4539,7 +4557,7 @@ status_t OMXCodec::setFLACFormat(const sp<MetaData> &meta)
param.nChannels = numChannels;
param.nSampleRate = sampleRate;
- //param.nBitsPerSample = bitsPerSample;
+ param.nBitsPerSample = bitsPerSample;
err = mOMX->setParameter(
mNode, OMX_IndexParamAudioFlac, &param, sizeof(param));
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 5187b63914..2313a16161 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -603,20 +603,20 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, const sp<MetaData
if (!meta->findInt32(kKeySampleBits, &bitWidth)) {
ALOGV("bits per sample not set, using default %d", bitWidth);
}
- info.bit_width = bitWidth;
+ info.bit_width = bitWidth >= 24 ? 24 : bitWidth;
#endif
info.format = AUDIO_FORMAT_INVALID;
if (mapMimeToAudioFormat(info.format, mime) != OK) {
ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
return false;
- } else {
+ } else if (audio_is_linear_pcm(info.format) || audio_is_offload_pcm(info.format)) {
#if defined(QCOM_HARDWARE) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
// Override audio format for PCM offload
- if (bitWidth == 24) {
+ if (bitWidth >= 24) {
ALOGD("24-bit PCM offload enabled");
info.format = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD;
- } else if (info.format == AUDIO_FORMAT_PCM_16_BIT) {
+ } else {
info.format = AUDIO_FORMAT_PCM_16_BIT_OFFLOAD;
}
#endif
@@ -628,7 +628,7 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, const sp<MetaData
return false;
}
- ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
+ ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, info.format);
// check whether it is ELD/LD/main content -> no offloading
// FIXME: this should depend on audio DSP capabilities. mapMimeToAudioFormat() should use the
@@ -682,7 +682,11 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, const sp<MetaData
bool canOffload = AudioSystem::isOffloadSupported(info);
#if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS)
- ExtendedUtils::updateOutputBitWidth(meta, canOffload);
+ // If we can't offload a 24-bit stream, we need to downgrade
+ // it to 16-bits. Codec will reconfigure for new bit width.
+ if (audio_is_offload_pcm(info.format)) {
+ ExtendedUtils::updateOutputBitWidth(meta, canOffload);
+ }
#endif
return canOffload;