Merge "audio: fix crashes upon USB device connection" into lmp-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 7e4a1d9..a68adea 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -251,7 +251,7 @@
status_t setupAACCodec(
bool encoder,
int32_t numChannels, int32_t sampleRate, int32_t bitRate,
- int32_t aacProfile, bool isADTS);
+ int32_t aacProfile, bool isADTS, int32_t sbrMode);
status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 5b6e59e..b81674d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1289,16 +1289,20 @@
err = INVALID_OPERATION;
} else {
int32_t isADTS, aacProfile;
+ int32_t sbrMode;
if (!msg->findInt32("is-adts", &isADTS)) {
isADTS = 0;
}
if (!msg->findInt32("aac-profile", &aacProfile)) {
aacProfile = OMX_AUDIO_AACObjectNull;
}
+ if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
+ sbrMode = -1;
+ }
err = setupAACCodec(
encoder, numChannels, sampleRate, bitRate, aacProfile,
- isADTS != 0);
+ isADTS != 0, sbrMode);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
@@ -1460,7 +1464,7 @@
status_t ACodec::setupAACCodec(
bool encoder, int32_t numChannels, int32_t sampleRate,
- int32_t bitRate, int32_t aacProfile, bool isADTS) {
+ int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode) {
if (encoder && isADTS) {
return -EINVAL;
}
@@ -1527,6 +1531,32 @@
profile.nAACERtools = OMX_AUDIO_AACERNone;
profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
+ switch (sbrMode) {
+ case 0:
+ // disable sbr
+ profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
+ profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ case 1:
+ // enable single-rate sbr
+ profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
+ profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ case 2:
+ // enable dual-rate sbr
+ profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
+ profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ case -1:
+ // enable both modes -> the codec will decide which mode should be used
+ profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
+ profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ default:
+ // unsupported sbr mode
+ return BAD_VALUE;
+ }
+
err = mOMX->setParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 6093621..35aa883 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include "SoftAACEncoder2.h"
+#include <OMX_AudioExt.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/hexdump.h>
@@ -44,6 +45,8 @@
mNumChannels(1),
mSampleRate(44100),
mBitRate(0),
+ mSBRMode(-1),
+ mSBRRatio(0),
mAACProfile(OMX_AUDIO_AACObjectLC),
mSentCodecSpecificData(false),
mInputSize(0),
@@ -156,6 +159,41 @@
aacParams->nSampleRate = mSampleRate;
aacParams->nFrameLength = 0;
+ switch (mSBRMode) {
+ case 1: // sbr on
+ switch (mSBRRatio) {
+ case 0:
+ // set both OMX AAC tool flags
+ aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
+ aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ case 1:
+ // set single-rate SBR active
+ aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
+ aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ case 2:
+ // set dual-rate SBR active
+ aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
+ aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ default:
+ ALOGE("invalid SBR ratio %d", mSBRRatio);
+ TRESPASS();
+ }
+ break;
+ case 0: // sbr off
+ case -1: // sbr undefined
+ aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
+ aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
+ break;
+ default:
+ ALOGE("invalid SBR mode %d", mSBRMode);
+ TRESPASS();
+ }
+
+
+
return OMX_ErrorNone;
}
@@ -243,6 +281,23 @@
mAACProfile = aacParams->eAACProfile;
}
+ if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
+ && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
+ mSBRMode = 0;
+ mSBRRatio = 0;
+ } else if ((aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
+ && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
+ mSBRMode = 1;
+ mSBRRatio = 1;
+ } else if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
+ && (aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
+ mSBRMode = 1;
+ mSBRRatio = 2;
+ } else {
+ mSBRMode = -1; // codec default sbr mode
+ mSBRRatio = 0;
+ }
+
if (setAudioParams() != OK) {
return OMX_ErrorUndefined;
}
@@ -305,11 +360,11 @@
}
status_t SoftAACEncoder2::setAudioParams() {
- // We call this whenever sample rate, number of channels or bitrate change
+ // We call this whenever sample rate, number of channels, bitrate or SBR mode change
// in reponse to setParameter calls.
- ALOGV("setAudioParams: %u Hz, %u channels, %u bps",
- mSampleRate, mNumChannels, mBitRate);
+ ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
+ mSampleRate, mNumChannels, mBitRate, mSBRMode, mSBRRatio);
if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT,
getAOTFromProfile(mAACProfile))) {
@@ -335,6 +390,24 @@
return UNKNOWN_ERROR;
}
+ if (mSBRMode != -1 && mAACProfile == OMX_AUDIO_AACObjectELD) {
+ if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) {
+ ALOGE("Failed to set AAC encoder parameters");
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ /* SBR ratio parameter configurations:
+ 0: Default configuration wherein SBR ratio is configured depending on audio object type by
+ the FDK.
+ 1: Downsampled SBR (default for ELD)
+ 2: Dualrate SBR (default for HE-AAC)
+ */
+ if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) {
+ ALOGE("Failed to set AAC encoder parameters");
+ return UNKNOWN_ERROR;
+ }
+
return OK;
}
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
index 2603f4f..bce9c24 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
@@ -53,6 +53,8 @@
OMX_U32 mNumChannels;
OMX_U32 mSampleRate;
OMX_U32 mBitRate;
+ OMX_S32 mSBRMode;
+ OMX_S32 mSBRRatio;
OMX_U32 mAACProfile;
bool mSentCodecSpecificData;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 3a9c162..c519593 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -88,6 +88,7 @@
STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 9721e13..046988e 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -810,7 +810,9 @@
return res;
}
}
- if (params.zslMode && !params.recordingHint) {
+
+ if (params.zslMode && !params.recordingHint &&
+ getRecordingStreamId() == NO_STREAM) {
res = updateProcessorStream(mZslProcessor, params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update ZSL stream: %s (%d)",
@@ -1033,6 +1035,36 @@
return res;
}
}
+
+ if (mZslProcessor->getStreamId() != NO_STREAM) {
+ ALOGV("%s: Camera %d: Clearing out zsl stream before "
+ "creating recording stream", __FUNCTION__, mCameraId);
+ res = mStreamingProcessor->stopStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream",
+ __FUNCTION__, mCameraId);
+ return res;
+ }
+ res = mDevice->waitUntilDrained();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
+ __FUNCTION__, mCameraId, strerror(-res), res);
+ }
+ res = mZslProcessor->clearZslQueue();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Can't clear zsl queue",
+ __FUNCTION__, mCameraId);
+ return res;
+ }
+ res = mZslProcessor->deleteStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to delete zsl stream before "
+ "record: %s (%d)", __FUNCTION__, mCameraId,
+ strerror(-res), res);
+ return res;
+ }
+ }
+
// Disable callbacks if they're enabled; can't record and use callbacks,
// and we can't fail record start without stagefright asserting.
params.previewCallbackFlags = 0;