summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmedia/Android.mk2
-rwxr-xr-xmedia/libstagefright/ACodec.cpp5
-rw-r--r--media/libstagefright/Android.mk9
-rw-r--r--media/libstagefright/AudioPlayer.cpp4
-rw-r--r--media/libstagefright/ExtendedMediaDefs.cpp4
-rw-r--r--media/libstagefright/FLACDecoder.cpp311
-rw-r--r--media/libstagefright/NuMediaExtractor.cpp24
-rw-r--r--media/libstagefright/OMXCodec.cpp37
-rw-r--r--media/libstagefright/Utils.cpp16
-rw-r--r--media/libstagefright/include/FLACDecoder.h90
-rw-r--r--services/audioflinger/Android.mk2
11 files changed, 486 insertions, 18 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index e8c2db26d1..c3964e34cf 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -97,7 +97,7 @@ endif #TARGET_ENABLE_AV_ENHANCEMENTS
#QTI Resampler
ifeq ($(call is-vendor-board-platform,QCOM),true)
-ifeq ($(strip $(BOARD_USES_QCOM_RESAMPLER)),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true)
LOCAL_CFLAGS += -DQTI_RESAMPLER
endif
endif
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index a3d54a47c3..48503be365 100755
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1023,8 +1023,13 @@ status_t ACodec::setComponentRole(
"video_decoder.vp9", "video_encoder.vp9" },
{ MEDIA_MIMETYPE_AUDIO_RAW,
"audio_decoder.raw", "audio_encoder.raw" },
+#ifdef QTI_FLAC_DECODER
+ { MEDIA_MIMETYPE_AUDIO_FLAC,
+ "audio_decoder.raw", NULL },
+#else
{ MEDIA_MIMETYPE_AUDIO_FLAC,
"audio_decoder.flac", "audio_encoder.flac" },
+#endif
{ MEDIA_MIMETYPE_AUDIO_MSGSM,
"audio_decoder.gsm", "audio_encoder.gsm" },
};
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index c5b12ce32a..5e0ed1dfff 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -149,6 +149,15 @@ LOCAL_SHARED_LIBRARIES := \
libz \
libpowermanager
+#QTI FLAC Decoder
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
+LOCAL_SRC_FILES += FLACDecoder.cpp
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-flac
+LOCAL_CFLAGS := -DQTI_FLAC_DECODER
+endif
+endif
+
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
libstagefright_aacenc \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index ba7678d5a7..dc20fb12da 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -44,6 +44,10 @@
#include "include/AwesomePlayer.h"
+#ifdef ENABLE_AV_ENHANCEMENTS
+#include "QCMetaData.h"
+#endif
+
namespace android {
AudioPlayer::AudioPlayer(
diff --git a/media/libstagefright/ExtendedMediaDefs.cpp b/media/libstagefright/ExtendedMediaDefs.cpp
index 92b8e581f5..4ddb8d387d 100644
--- a/media/libstagefright/ExtendedMediaDefs.cpp
+++ b/media/libstagefright/ExtendedMediaDefs.cpp
@@ -52,6 +52,10 @@ const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA = "video/qc-matroska";
const char *MEDIA_MIMETYPE_CONTAINER_QCOGG = "video/qc-ogg";
const char *MEDIA_MIMETYPE_CONTAINER_QCFLV = "video/qc-flv";
const char *MEDIA_MIMETYPE_VIDEO_VPX = "video/x-vnd.on2.vp8"; //backward compatibility
+#ifdef QTI_FLAC_DECODER
const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC = "audio/qti-flac";
+#else
+const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC = "audio/flac";
+#endif
} // namespace android
diff --git a/media/libstagefright/FLACDecoder.cpp b/media/libstagefright/FLACDecoder.cpp
new file mode 100644
index 0000000000..78faf0ae9e
--- /dev/null
+++ b/media/libstagefright/FLACDecoder.cpp
@@ -0,0 +1,311 @@
+/*Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "FLACDecoder"
+//#define LOG_NDEBUG 0
+//#define VERY_VERY_VERBOSE_LOGGING
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while (0)
+#endif
+
+#include <utils/Log.h>
+#include <dlfcn.h>
+
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include "include/FLACDecoder.h"
+#ifdef ENABLE_AV_ENHANCEMENTS
+#include "QCMetaData.h"
+#endif
+
+namespace android {
+
+static const char* FLAC_DECODER_LIB = "libFlacSwDec.so";
+
+FLACDecoder::FLACDecoder(const sp<MediaSource> &source)
+ : mSource(source),
+ mInputBuffer(NULL),
+ mStarted(false),
+ mInitStatus(false),
+ mBufferGroup(NULL),
+ mNumFramesOutput(0),
+ mAnchorTimeUs(0),
+ mLibHandle(dlopen(FLAC_DECODER_LIB, RTLD_LAZY)),
+ mOutBuffer(NULL),
+ mDecoderInit(NULL),
+ mProcessData(NULL) {
+ ALOGD("qti_flac: Instantiate FLACDecoder");
+ if (mLibHandle != NULL) {
+ mDecoderInit = (DecoderInit) dlsym (mLibHandle, "CFlacDecoderLib_Meminit");
+ mProcessData = (DecoderLib_Process) dlsym (mLibHandle, "CFlacDecoderLib_Process");
+ init();
+ }
+}
+
+FLACDecoder::~FLACDecoder() {
+ ALOGD("qti_flac: Destroy FLACDecoder");
+ if (mStarted) {
+ stop();
+ }
+ if (mLibHandle != NULL) {
+ dlclose(mLibHandle);
+ }
+ mLibHandle = NULL;
+}
+
+void FLACDecoder::init() {
+ ALOGV("qti_flac: FLACDecoder::init");
+ int result, bitWidth = 16; //currently, only 16 bit is supported
+ memset(&pFlacDecState,0,sizeof(CFlacDecState));
+ (*mDecoderInit)(&pFlacDecState, &result, bitWidth);
+
+ if (result != DEC_SUCCESS) {
+ ALOGE("qti_flac: CSIM decoder init failed! Result %d", result);
+ return;
+ }
+ else {
+ mInitStatus = true;
+ }
+
+ sp<MetaData> srcFormat = mSource->getFormat();
+
+ mMeta = new MetaData;
+
+ int32_t sampleBits, minBlkSize, maxBlkSize, minFrmSize, maxFrmSize;
+ CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
+ CHECK(srcFormat->findInt32(kKeySampleRate, &mSampleRate));
+ CHECK(srcFormat->findInt32(kKeySampleBits, &sampleBits));
+ CHECK(srcFormat->findInt32(kKeyMinBlkSize, &minBlkSize));
+ CHECK(srcFormat->findInt32(kKeyMaxBlkSize, &maxBlkSize));
+ CHECK(srcFormat->findInt32(kKeyMinFrmSize, &minFrmSize));
+ CHECK(srcFormat->findInt32(kKeyMaxFrmSize, &maxFrmSize));
+
+ parserInfoToPass.i32NumChannels = mNumChannels;
+ parserInfoToPass.i32SampleRate = mSampleRate;
+ parserInfoToPass.i32BitsPerSample = sampleBits;
+ parserInfoToPass.i32MinBlkSize = minBlkSize;
+ parserInfoToPass.i32MaxBlkSize = maxBlkSize;
+ parserInfoToPass.i32MinFrmSize = minFrmSize;
+ parserInfoToPass.i32MaxFrmSize = maxFrmSize;
+
+ ALOGV("qti_flac: i32NumChannels = %d", parserInfoToPass.i32NumChannels);
+ ALOGV("qti_flac: i32SampleRate = %d", parserInfoToPass.i32SampleRate);
+ ALOGV("qti_flac: i32BitsPerSample = %d", parserInfoToPass.i32BitsPerSample);
+ ALOGV("qti_flac: i32MinBlkSize = %d", parserInfoToPass.i32MinBlkSize);
+ ALOGV("qti_flac: i32MaxBlkSize = %d", parserInfoToPass.i32MaxBlkSize);
+ ALOGV("qti_flac: i32MinFrmSize = %d", parserInfoToPass.i32MinFrmSize);
+ ALOGV("qti_flac: i32MaxFrmSize = %d", parserInfoToPass.i32MaxFrmSize);
+
+ setMetaData(&pFlacDecState, &parserInfoToPass);
+
+ mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+
+ int64_t durationUs;
+ if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
+ mMeta->setInt64(kKeyDuration, durationUs);
+ }
+
+ ALOGV("qti_flac: durationUs = %lld", durationUs);
+ mMeta->setCString(kKeyDecoderComponent, "FLACDecoder");
+ mMeta->setInt32(kKeySampleRate, mSampleRate);
+ mMeta->setInt32(kKeyChannelCount, mNumChannels);
+
+ mOutBuffer = (uint16_t *) malloc (FLAC_INSTANCE_SIZE);
+ mTmpBuf = (uint16_t *) malloc (FLAC_INSTANCE_SIZE);
+ ALOGV("qti_flac: FLACDecoder::init done");
+}
+
+void FLACDecoder::setMetaData(CFlacDecState* pFlacDecState,
+ FLACDec_ParserInfo* parserInfoToPass) {
+ ALOGV("qti_flac: FLACDecoder::setMetadata");
+ stFLACDec* pstFLACDec=(stFLACDec*)(pFlacDecState->m_pFlacDecoder);
+ memcpy(&pstFLACDec->MetaDataBlocks.MetaDataStrmInfo,parserInfoToPass,sizeof(FLACDec_ParserInfo));
+ pFlacDecState->m_bIsStreamInfoPresent=1;
+
+ pFlacDecState->ui32MaxBlockSize=pstFLACDec->MetaDataBlocks.MetaDataStrmInfo.i32MaxBlkSize;
+
+ memcpy(pFlacDecState->pFlacDecMetaDataStrmInfo,parserInfoToPass,sizeof(FLACDec_ParserInfo));
+ ALOGV("qti_flac: FLACDecoder::setMetadata done");
+
+}
+
+status_t FLACDecoder::start(MetaData *params) {
+ ALOGV("qti_flac: FLACDecoder::start");
+
+ CHECK(!mStarted);
+ CHECK(mInitStatus);
+
+ mBufferGroup = new MediaBufferGroup;
+ mBufferGroup->add_buffer(new MediaBuffer(FLAC_INSTANCE_SIZE));
+
+ mSource->start();
+ mAnchorTimeUs = 0;
+ mNumFramesOutput = 0;
+ mStarted = true;
+
+ ALOGV("qti_flac: FLACDecoder::start done");
+ return OK;
+}
+
+status_t FLACDecoder::stop() {
+ ALOGV("qti_flac: FLACDecoder::stop");
+
+ CHECK(mStarted);
+ CHECK(mInitStatus);
+
+ if (mInputBuffer) {
+ mInputBuffer->release();
+ mInputBuffer = NULL;
+ }
+
+ delete mBufferGroup;
+ mBufferGroup = NULL;
+
+ mSource->stop();
+ mStarted = false;
+
+ free(mOutBuffer);
+ free(mTmpBuf);
+
+ ALOGV("qti_flac: FLACDecoder::stop done");
+ return OK;
+}
+
+sp<MetaData> FLACDecoder::getFormat() {
+ ALOGV("qti_flac: FLACDecoder::getFormat");
+ CHECK(mInitStatus);
+ ALOGV("qti_flac: FLACDecoder::getFormat done");
+ return mMeta;
+}
+
+status_t FLACDecoder::read(MediaBuffer **out, const ReadOptions* options) {
+ int err = 0;
+ *out = NULL;
+ uint32 blockSize, usedBitstream, availLength = 0;
+ uint32 flacOutputBufSize = FLAC_OUTPUT_BUFFER_SIZE;
+ int *status = 0;
+
+ bool seekSource = false, eos = false;
+
+ if (!mInitStatus) {
+ return NO_INIT;
+ }
+
+ int64_t seekTimeUs;
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ ALOGD("qti_flac: Seek to %lld", seekTimeUs);
+ CHECK(seekTimeUs >= 0);
+ mNumFramesOutput = 0;
+ seekSource = true;
+
+ if (mInputBuffer) {
+ mInputBuffer->release();
+ mInputBuffer = NULL;
+ }
+ }
+ else {
+ seekTimeUs = -1;
+ }
+
+ if (mInputBuffer) {
+ mInputBuffer->release();
+ mInputBuffer = NULL;
+ }
+
+ if (!eos) {
+ err = mSource->read(&mInputBuffer, options);
+ if (err != OK) {
+ ALOGE("qti_flac: Parser returned %d", err);
+ eos = true;
+ return err;
+ }
+ }
+
+ int64_t timeUs;
+ if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
+ mAnchorTimeUs = timeUs;
+ mNumFramesOutput = 0;
+ ALOGVV("qti_flac: mAnchorTimeUs %lld", mAnchorTimeUs);
+ }
+ else {
+ CHECK(seekTimeUs < 0);
+ }
+
+ if (!eos) {
+ if (mInputBuffer) {
+ ALOGVV("qti_flac: Parser filled %d bytes", mInputBuffer->range_length());
+ availLength = mInputBuffer->range_length();
+ status = (*mProcessData)(&pFlacDecState,
+ (uint8*)mInputBuffer->data(),
+ availLength,
+ mOutBuffer,
+ &flacOutputBufSize,
+ &usedBitstream,
+ &blockSize);
+ }
+
+ ALOGVV("qti_flac: status %d, availLength %d, usedBitstream %d, blockSize %d",
+ (int)status, availLength, usedBitstream, blockSize);
+
+ MediaBuffer *buffer;
+ CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK);
+
+ buffer->set_range(0, blockSize*mNumChannels*2);
+
+ uint16_t *ptr = (uint16_t *) mOutBuffer;
+
+ //Interleave the output from decoder for multichannel clips.
+ if (mNumChannels > 1) {
+ for (uint32_t k = 0; k < blockSize; k++) {
+ for (uint32_t i = k, j = mNumChannels*k; i < blockSize*mNumChannels; i += blockSize, j++) {
+ mTmpBuf[j] = ptr[i];
+ }
+ }
+ memcpy((uint16_t *)buffer->data(), mTmpBuf, blockSize*mNumChannels*2);
+ }
+ else {
+ memcpy((uint16_t *)buffer->data(), mOutBuffer, blockSize*mNumChannels*2);
+ }
+
+ int64_t time = 0;
+ time = mAnchorTimeUs + (mNumFramesOutput*1000000)/mSampleRate;
+ buffer->meta_data()->setInt64(kKeyTime, time);
+ mNumFramesOutput += blockSize;
+ ALOGVV("qti_flac: time = %lld", time);
+
+ *out = buffer;
+ }
+
+ return OK;
+}
+
+}
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 7bc7da2425..c263d244d0 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -23,6 +23,9 @@
#include "include/ESDS.h"
#include "include/NuCachedSource2.h"
#include "include/WVMExtractor.h"
+#ifdef QTI_FLAC_DECODER
+#include "include/FLACDecoder.h"
+#endif
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -275,24 +278,29 @@ status_t NuMediaExtractor::selectTrack(size_t index) {
return OK;
}
}
-
sp<MediaSource> source = mImpl->getTrack(index);
-
- CHECK_EQ((status_t)OK, source->start());
-
mSelectedTracks.push();
TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
- info->mSource = source;
+ const char *mime;
+ CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
+#ifdef QTI_FLAC_DECODER
+ sp<MediaSource> mFlacSource = new FLACDecoder(source);
+ info->mSource = mFlacSource;
+ mFlacSource->start();
+#endif
+ } else {
+ CHECK_EQ((status_t)OK, source->start());
+ info->mSource = source;
+ }
+
info->mTrackIndex = index;
info->mFinalResult = OK;
info->mSample = NULL;
info->mSampleTimeUs = -1ll;
info->mTrackFlags = 0;
- const char *mime;
- CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
-
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
info->mTrackFlags |= kIsVorbis;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index f21a778093..7baede4be7 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
*
* Not a Contribution
*
@@ -76,6 +76,10 @@
#include <ctype.h>
#endif
+#ifdef QTI_FLAC_DECODER
+#include "include/FLACDecoder.h"
+#endif
+
namespace android {
#ifdef USE_SAMSUNG_COLORFORMAT
@@ -120,9 +124,14 @@ static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaDa
#define FACTORY_REF(name) { #name, Make##name },
+#ifdef QTI_FLAC_DECODER
+FACTORY_CREATE(FLACDecoder)
+#endif
+
#ifdef QCOM_DIRECTTRACK
FACTORY_CREATE(MP3Decoder)
#endif
+
FACTORY_CREATE_ENCODER(AACEncoder)
static sp<MediaSource> InstantiateSoftwareEncoder(
@@ -146,7 +155,7 @@ static sp<MediaSource> InstantiateSoftwareEncoder(
return NULL;
}
-#ifdef QCOM_DIRECTTRACK
+#if defined(QCOM_DIRECTTRACK) || defined (QTI_FLAC_DECODER)
static sp<MediaSource> InstantiateSoftwareDecoder(
const char *name, const sp<MediaSource> &source) {
struct FactoryInfo {
@@ -154,7 +163,12 @@ static sp<MediaSource> InstantiateSoftwareDecoder(
sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
};
static const FactoryInfo kFactoryInfo[] = {
+#ifdef QCOM_DIRECTTRACK
FACTORY_REF(MP3Decoder)
+#endif
+#ifdef QTI_FLAC_DECODER
+ FACTORY_REF(FLACDecoder)
+#endif
};
for (size_t i = 0;
i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
@@ -165,6 +179,7 @@ static sp<MediaSource> InstantiateSoftwareDecoder(
return NULL;
}
#endif
+
#undef FACTORY_CREATE_ENCODER
#undef FACTORY_REF
@@ -509,14 +524,20 @@ sp<MediaSource> OMXCodec::Create(
componentName = tmp.c_str();
}
+ sp<MediaSource> softwareCodec;
if (createEncoder) {
- sp<MediaSource> softwareCodec =
- InstantiateSoftwareEncoder(componentName, source, meta);
- if (softwareCodec != NULL) {
- ALOGV("Successfully allocated software codec '%s'", componentName);
+ softwareCodec = InstantiateSoftwareEncoder(componentName, source, meta);
+ }
+#ifdef QTI_FLAC_DECODER
+ else {
+ softwareCodec = InstantiateSoftwareDecoder(componentName, source);
+ }
+#endif
- return softwareCodec;
- }
+ if (softwareCodec != NULL) {
+ ALOGV("Successfully allocated software codec '%s'", componentName);
+
+ return softwareCodec;
}
#ifdef QCOM_HARDWARE
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 2313a16161..cc44814388 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -509,6 +509,7 @@ status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
int32_t delaySamples = 0;
int32_t paddingSamples = 0;
int32_t isADTS = 0;
+ int32_t minBlkSize, maxBlkSize, minFrmSize, maxFrmSize; //FLAC params
AudioParameter param = AudioParameter();
@@ -530,6 +531,20 @@ status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
if (meta->findInt32(kKeyIsADTS, &isADTS)) {
param.addInt(String8(AUDIO_OFFLOAD_CODEC_FORMAT), 0x02 /*SND_AUDIOSTREAMFORMAT_MP4ADTS*/);
}
+#ifdef ENABLE_AV_ENHANCEMENTS
+ if (meta->findInt32(kKeyMinBlkSize, &minBlkSize)) {
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE), minBlkSize);
+ }
+ if (meta->findInt32(kKeyMaxBlkSize, &maxBlkSize)) {
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE), maxBlkSize);
+ }
+ if (meta->findInt32(kKeyMinFrmSize, &minFrmSize)) {
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE), minFrmSize);
+ }
+ if (meta->findInt32(kKeyMaxFrmSize, &maxFrmSize)) {
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE), maxFrmSize);
+ }
+#endif
ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
"delaySample %d, paddingSample %d", bitRate, sampleRate,
@@ -561,6 +576,7 @@ static const struct mime_conv_t mimeLookup[] = {
{ MEDIA_MIMETYPE_AUDIO_QCELP, AUDIO_FORMAT_QCELP },
{ MEDIA_MIMETYPE_AUDIO_WMA, AUDIO_FORMAT_WMA },
{ MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, AUDIO_FORMAT_MP2 },
+ { MEDIA_MIMETYPE_CONTAINER_QTIFLAC, AUDIO_FORMAT_FLAC },
#endif
{ 0, AUDIO_FORMAT_INVALID }
};
diff --git a/media/libstagefright/include/FLACDecoder.h b/media/libstagefright/include/FLACDecoder.h
new file mode 100644
index 0000000000..2d14347b61
--- /dev/null
+++ b/media/libstagefright/include/FLACDecoder.h
@@ -0,0 +1,90 @@
+/*Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC_DECODER
+#define FLAC_DECODER
+#include "FLACDec_Wrapper.h"
+#include "FLACDec_BitStream.h"
+#include "FLACDec_MetaData.h"
+#include "FLACDec_Struct.h"
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#define FLAC_OUTPUT_BUFFER_SIZE (8192*8)*4*8
+#define FLAC_INSTANCE_SIZE 2048 + MAXINPBUFFER + 65536*8*4
+
+namespace android {
+
+struct MediaBufferGroup;
+
+class FLACDecoder : public MediaSource {
+public:
+ FLACDecoder(const sp<MediaSource> &source);
+ ~FLACDecoder();
+ void init();
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+ virtual status_t read(MediaBuffer **buffer, const ReadOptions *options);
+
+private:
+ sp<MediaSource> mSource;
+ sp<MetaData> mMeta;
+ MediaBuffer *mInputBuffer;
+ int32_t mNumChannels;
+ int32_t mSampleRate;
+ bool mStarted;
+ bool mInitStatus;
+ MediaBufferGroup *mBufferGroup;
+ int64_t mNumFramesOutput;
+ int64_t mAnchorTimeUs;
+
+ CFlacDecState pFlacDecState;
+ FLACDec_ParserInfo parserInfoToPass;
+
+ void *mLibHandle;
+ void *mOutBuffer;
+ uint16_t *mTmpBuf;
+
+ void setMetaData(CFlacDecState* pFlacDecState,
+ FLACDec_ParserInfo* parserInfoToPass);
+
+ typedef void* (*DecoderInit) (CFlacDecState* pFlacDecState, int* nRes, int bitWidth);
+
+ typedef int* (*DecoderLib_Process) (CFlacDecState* pFlacDecState, uint8* pInBitStream,
+ uint32 nActualDataLen, void *pOutSamples,
+ uint32* uFlacOutputBufSize, uint32* usedBitstream,
+ uint32* blockSize);
+
+ DecoderInit mDecoderInit;
+ DecoderLib_Process mProcessData;
+};
+
+} // namespace android
+
+#endif //FLAC_DECODER
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 08bdeab2f6..d0b712d9f7 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -68,7 +68,7 @@ LOCAL_SHARED_LIBRARIES := \
#QTI Resampler
ifeq ($(call is-vendor-board-platform,QCOM),true)
-ifeq ($(strip $(BOARD_USES_QCOM_RESAMPLER)),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true)
LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
LOCAL_SHARED_LIBRARIES += libqct_resampler