diff options
-rw-r--r-- | media/libmedia/Android.mk | 2 | ||||
-rwxr-xr-x | media/libstagefright/ACodec.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/Android.mk | 9 | ||||
-rw-r--r-- | media/libstagefright/AudioPlayer.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/ExtendedMediaDefs.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/FLACDecoder.cpp | 311 | ||||
-rw-r--r-- | media/libstagefright/NuMediaExtractor.cpp | 24 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 37 | ||||
-rw-r--r-- | media/libstagefright/Utils.cpp | 16 | ||||
-rw-r--r-- | media/libstagefright/include/FLACDecoder.h | 90 | ||||
-rw-r--r-- | services/audioflinger/Android.mk | 2 |
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 |