summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSatya Krishna Pindiproli <satyak@codeaurora.org>2014-01-10 16:41:51 +0530
committerSteve Kondik <shade@chemlab.org>2014-11-01 15:17:41 -0700
commita604d504b155655ddf209a522b18cee051f959f7 (patch)
tree2a64c94265560115fc50e183a6f5a7f8881dc67f
parent6c52b69f9194288354cd6668baacc5af94b37b7d (diff)
downloadframeworks_av-a604d504b155655ddf209a522b18cee051f959f7.tar.gz
frameworks_av-a604d504b155655ddf209a522b18cee051f959f7.tar.bz2
frameworks_av-a604d504b155655ddf209a522b18cee051f959f7.zip
libstagefright: Wrapper for FLAC CSIM decoder
A new FLAC decoder is being used to decode 24 bit clips with very high sample rate (192kHz) and this code is a wrapper to that decoder. The decoder will be used only if the extended extractor is invoked. CRs-Fixed: 609395 Change-Id: I59a33e0e00fd2fc6e88318d0e597519579aa56e9 libstagefright: Optimize the wrapper for FLAC CSIM decoder Move dlsym calls to constructor and do all memory allocations only once to avoid fragmentation of heap. Also add support to handle multichannel PCM from the decoder. Change-Id: I7feace450d692528eb00c39df4bffff2c5528ada libstagefright: Modify the path of FLAC headers The location of the headers of the FLAC CSIM library has changed. Modify the include path to reflect the right location. Change-Id: I13630a089716d8c1b35bfc5451d83ba3f3ade6a7 libstagefright: Add support for FLAC superset clips Memory requirements for FLAC superset content are high as each channel can contain upto 64k bytes. Redefine the macros to meet these requirements. Also initialize the decoder to give data in configurable bitWidth. Currently, only 16 bit output is supported though. Change-Id: I60b7b329bb3c0653f7a7c0fbe55229aaf5d62918 libstagefright: Enable ACodec path for QTI FLAC solution Use the OMX component of Google's RAW decoder for FLAC codec and setup NuMediaExtractor to extract PCM samples from FLACDecoder. CRs-Fixed: 643618 Change-Id: Iaa7594e4d882b52157f49e7c9b2da1861ba49568 libstagefright: Improve logging for QTI FLAC Decoder Edit logs to print relevant messages when QTI FLAC Decoder is used to decode FLAC content. CRs-Fixed: 648845 Change-Id: I1fb5c4f5757dc54c37ac255fda83cb1f96f8504d libstagefright: Add FLAC format in compress offload path - Add mime type mapping for FLAC - Add flac codec specific params in offload metadata - Set bit width based on kKeySampleBits Change-Id: I8781edd352346355d6f9a4274d29b85d6f2e4b55 audio: remove key definitions for FLAC meta data - Remove FLAC meta data specific keys in metaData.h - Define the same keys in QCMetaData.h Change-Id: I7249c223d321d59923e970898ae2f4d112ed8ea5 audio: update QTI resampler feature flag - update QTI resampler feature flag to AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER Change-Id: I79d8323911464dc6777d26b11b4c500782d7a548 audio: update QTI FLAC decoder feature flag - update QTI FLAC decoder feature flag to AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER Change-Id: Id4737f4bc31eb2b8f3c9dc36ca2bdac91e327adc
-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