summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libavextensions/stagefright/AVExtensions.h11
-rw-r--r--media/libavextensions/stagefright/AVUtils.cpp14
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp19
-rw-r--r--media/libstagefright/Utils.cpp7
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.cpp41
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.h3
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.cpp31
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.h3
-rw-r--r--services/audiopolicy/common/managerdefinitions/Android.mk3
-rw-r--r--services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h12
10 files changed, 134 insertions, 10 deletions
diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h
index e75499f..832fc28 100644
--- a/media/libavextensions/stagefright/AVExtensions.h
+++ b/media/libavextensions/stagefright/AVExtensions.h
@@ -128,6 +128,17 @@ struct AVUtils {
virtual bool canOffloadAPE(const sp<MetaData> &meta);
+ virtual int32_t getAudioMaxInputBufferSize(audio_format_t audioFormat,
+ const sp<AMessage> &);
+
+ virtual bool mapAACProfileToAudioFormat(const sp<MetaData> &,
+ audio_format_t &,
+ uint64_t /*eAacProfile*/);
+
+ virtual bool mapAACProfileToAudioFormat(const sp<AMessage> &,
+ audio_format_t &,
+ uint64_t /*eAacProfile*/);
+
virtual void extractCustomCameraKeys(
const CameraParameters& /*params*/, sp<MetaData> &/*meta*/) {}
virtual void printFileName(int /*fd*/) {}
diff --git a/media/libavextensions/stagefright/AVUtils.cpp b/media/libavextensions/stagefright/AVUtils.cpp
index 5113446..9219fc2 100644
--- a/media/libavextensions/stagefright/AVUtils.cpp
+++ b/media/libavextensions/stagefright/AVUtils.cpp
@@ -105,6 +105,20 @@ bool AVUtils::canOffloadAPE(const sp<MetaData> &) {
return true;
}
+int32_t AVUtils::getAudioMaxInputBufferSize(audio_format_t, const sp<AMessage> &) {
+ return 0;
+}
+
+bool AVUtils::mapAACProfileToAudioFormat(const sp<MetaData> &, audio_format_t &,
+ uint64_t /*eAacProfile*/) {
+ return false ;
+}
+
+bool AVUtils::mapAACProfileToAudioFormat(const sp<AMessage> &, audio_format_t &,
+ uint64_t /*eAacProfile*/) {
+ return false ;
+}
+
bool AVUtils::isEnhancedExtension(const char *) {
return false;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 87e49bd..aa993a9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1688,12 +1688,24 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
if (audioFormat == AUDIO_FORMAT_AAC
&& format->findInt32("aac-profile", &aacProfile)) {
// Redefine AAC format as per aac profile
- mapAACProfileToAudioFormat(
- audioFormat,
- aacProfile);
+ int32_t isADTSSupported;
+ isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(format,
+ audioFormat,
+ aacProfile);
+ if (!isADTSSupported) {
+ mapAACProfileToAudioFormat(audioFormat,
+ aacProfile);
+ } else {
+ ALOGV("Format is AAC ADTS\n");
+ }
}
+ int32_t offloadBufferSize =
+ AVUtils::get()->getAudioMaxInputBufferSize(
+ audioFormat,
+ format);
audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
+
offloadInfo.duration_us = -1;
format->findInt64(
"durationUs", &offloadInfo.duration_us);
@@ -1705,6 +1717,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
offloadInfo.has_video = hasVideo;
offloadInfo.is_streaming = isStreaming;
offloadInfo.bit_width = bitWidth;
+ offloadInfo.offload_buffer_size = offloadBufferSize;
if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
ALOGV("openAudioSink: no change in offload mode");
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 935fbf7..e7d36dc 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -834,7 +834,12 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
// Offloading depends on audio DSP capabilities.
int32_t aacaot = -1;
if (meta->findInt32(kKeyAACAOT, &aacaot)) {
- mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
+ bool isADTSSupported = false;
+ isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(meta, info.format,
+ (OMX_AUDIO_AACPROFILETYPE) aacaot);
+ if (!isADTSSupported) {
+ mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
+ }
}
int32_t srate = -1;
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 965c55e..c945305 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -68,6 +68,8 @@ SoftAAC2::SoftAAC2(
mOutputBufferCount(0),
mSignalledError(false),
mLastInHeader(NULL),
+ mLastHeaderTimeUs(-1),
+ mNextOutBufferTimeUs(0),
mOutputPortSettingsChange(NONE) {
initPorts();
CHECK_EQ(initDecoder(), (status_t)OK);
@@ -492,6 +494,27 @@ int32_t SoftAAC2::outputDelayRingBufferSpaceLeft() {
return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
}
+void SoftAAC2::updateTimeStamp(int64_t inHeaderTimeUs) {
+ // use new input buffer timestamp as Anchor Time if its
+ // a) first buffer or
+ // b) first buffer post seek or
+ // c) different from last buffer timestamp
+ //If input buffer timestamp is same as last input buffer timestamp then
+ //treat this as a erroneous timestamp and ignore new input buffer
+ //timestamp and use last output buffer timestamp as Anchor Time.
+ int64_t anchorTimeUs = 0;
+ if ((mLastHeaderTimeUs != inHeaderTimeUs)) {
+ anchorTimeUs = inHeaderTimeUs;
+ mLastHeaderTimeUs = inHeaderTimeUs;
+ //Store current buffer's timestamp so that it can used as reference
+ //in cases where first frame/buffer is skipped/dropped.
+ //e.g to compensate decoder delay
+ mNextOutBufferTimeUs = inHeaderTimeUs;
+ } else {
+ anchorTimeUs = mNextOutBufferTimeUs;
+ }
+ mBufferTimestamps.add(anchorTimeUs);
+}
void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
@@ -618,7 +641,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
// insert buffer size and time stamp
mBufferSizes.add(inBufferLength[0]);
if (mLastInHeader != inHeader) {
- mBufferTimestamps.add(inHeader->nTimeStamp);
+ updateTimeStamp(inHeader->nTimeStamp);
mLastInHeader = inHeader;
} else {
int64_t currentTime = mBufferTimestamps.top();
@@ -630,7 +653,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
inBufferLength[0] = inHeader->nFilledLen;
mLastInHeader = inHeader;
- mBufferTimestamps.add(inHeader->nTimeStamp);
+ updateTimeStamp(inHeader->nTimeStamp);
mBufferSizes.add(inHeader->nFilledLen);
}
@@ -755,6 +778,14 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
if (inHeader && inHeader->nFilledLen == 0) {
inInfo->mOwnedByUs = false;
mInputBufferCount++;
+
+ //During Port reconfiguration current frames is skipped and next frame
+ //is sent for decoding.
+ //Update mNextOutBufferTimeUs with current frame's timestamp if port reconfiguration is
+ //happening in last frame of current buffer otherwise LastOutBufferTimeUs
+ //will be zero(post seek).
+ mNextOutBufferTimeUs = mBufferTimestamps.top() + mStreamInfo->aacSamplesPerFrame *
+ 1000000ll / mStreamInfo->aacSampleRate;
inQueue.erase(inQueue.begin());
mLastInHeader = NULL;
inInfo = NULL;
@@ -875,6 +906,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
*currentBufLeft -= decodedSize;
*nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
1000000ll / mStreamInfo->aacSampleRate;
+ mNextOutBufferTimeUs = *nextTimeStamp;
ALOGV("adjusted nextTimeStamp/size to %lld/%d",
(long long) *nextTimeStamp, *currentBufLeft);
} else {
@@ -882,6 +914,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
if (mBufferTimestamps.size() > 0) {
mBufferTimestamps.removeAt(0);
nextTimeStamp = &mBufferTimestamps.editItemAt(0);
+ mNextOutBufferTimeUs = *nextTimeStamp;
mBufferSizes.removeAt(0);
currentBufLeft = &mBufferSizes.editItemAt(0);
ALOGV("moved to next time/size: %lld/%d",
@@ -976,6 +1009,8 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
mDecodedSizes.clear();
mLastInHeader = NULL;
mEndOfInput = false;
+ mLastHeaderTimeUs = -1;
+ mNextOutBufferTimeUs = 0;
} else {
int avail;
while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
@@ -1038,6 +1073,8 @@ void SoftAAC2::onReset() {
mBufferSizes.clear();
mDecodedSizes.clear();
mLastInHeader = NULL;
+ mLastHeaderTimeUs = -1;
+ mNextOutBufferTimeUs = 0;
// To make the codec behave the same before and after a reset, we need to invalidate the
// streaminfo struct. This does that:
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index c3e4459..3fe958e 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -59,6 +59,8 @@ private:
size_t mOutputBufferCount;
bool mSignalledError;
OMX_BUFFERHEADERTYPE *mLastInHeader;
+ int64_t mLastHeaderTimeUs;
+ int64_t mNextOutBufferTimeUs;
Vector<int32_t> mBufferSizes;
Vector<int32_t> mDecodedSizes;
Vector<int64_t> mBufferTimestamps;
@@ -90,6 +92,7 @@ private:
int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferSamplesAvailable();
int32_t outputDelayRingBufferSpaceLeft();
+ void updateTimeStamp(int64_t inHeaderTimesUs);
DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
};
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index aeaea81..4c4da60 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -51,7 +51,9 @@ SoftMP3::SoftMP3(
mSignalledError(false),
mSawInputEos(false),
mSignalledOutputEos(false),
- mOutputPortSettingsChange(NONE) {
+ mOutputPortSettingsChange(NONE),
+ mLastAnchorTimeUs(-1),
+ mNextOutBufferTimeUs(0) {
initPorts();
initDecoder();
}
@@ -212,7 +214,7 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
-
+ int64_t tmpTime = 0;
while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
BufferInfo *inInfo = NULL;
OMX_BUFFERHEADERTYPE *inHeader = NULL;
@@ -227,7 +229,20 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
if (inHeader) {
if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
- mAnchorTimeUs = inHeader->nTimeStamp;
+ // use new input buffer timestamp as Anchor Time if its
+ // a) first buffer or
+ // b) first buffer post seek or
+ // c) different from last buffer timestamp
+ //If input buffer timestamp is same as last input buffer timestamp then
+ //treat this as a erroneous timestamp and ignore new input buffer
+ //timestamp and use last output buffer timestamp as Anchor Time.
+ if ((mLastAnchorTimeUs != inHeader->nTimeStamp)) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mLastAnchorTimeUs = inHeader->nTimeStamp;
+ } else {
+ mAnchorTimeUs = mNextOutBufferTimeUs;
+ }
+
mNumFramesOutput = 0;
}
@@ -326,7 +341,7 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
outHeader->nTimeStamp =
mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
-
+ tmpTime = outHeader->nTimeStamp;
if (inHeader) {
CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
@@ -351,6 +366,10 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
notifyFillBufferDone(outHeader);
outHeader = NULL;
}
+
+ if (tmpTime > 0) {
+ mNextOutBufferTimeUs = tmpTime;
+ }
}
void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
@@ -362,6 +381,8 @@ void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
mSignalledError = false;
mSawInputEos = false;
mSignalledOutputEos = false;
+ mLastAnchorTimeUs = -1;
+ mNextOutBufferTimeUs = 0;
}
}
@@ -398,6 +419,8 @@ void SoftMP3::onReset() {
mSawInputEos = false;
mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
+ mLastAnchorTimeUs = -1;
+ mNextOutBufferTimeUs = 0;
}
} // namespace android
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index f9e7b53..c769795 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -70,6 +70,9 @@ private:
AWAITING_ENABLED
} mOutputPortSettingsChange;
+ int64_t mLastAnchorTimeUs;
+ int64_t mNextOutBufferTimeUs;
+
void initPorts();
void initDecoder();
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index 10362f4..8c6a53c 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -47,6 +47,9 @@ endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_APE_OFFLOAD)),true)
LOCAL_CFLAGS += -DAPE_OFFLOAD_ENABLED
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AAC_ADTS_OFFLOAD)),true)
+LOCAL_CFLAGS += -DAAC_ADTS_OFFLOAD_ENABLED
+endif
endif
LOCAL_MODULE := libaudiopolicycomponents
diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
index cc91c63..4a394bb 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
@@ -217,6 +217,18 @@ const StringToEnum sFormatNameToEnumTable[] = {
#ifdef APE_OFFLOAD_ENABLED
STRING_TO_ENUM(AUDIO_FORMAT_APE),
#endif
+#ifdef AAC_ADTS_OFFLOAD_ENABLED
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_MAIN),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LC),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SSR),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LTP),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V1),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SCALABLE),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ERLC),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LD),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2),
+ STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ELD),
+#endif
};
const StringToEnum sOutChannelsNameToEnumTable[] = {