From 43cffaf845f3596f7f1b6c8cc5e0c9672a0a5c7d Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 26 Sep 2014 16:26:21 -0700 Subject: [PATCH 01/23] effects: miscellaneous fixes fixes of KW issues 8887, 8888 Change-Id: I824daa76d23456fed2c299c59f934d3e2ac78b84 --- media/libeffects/factory/EffectsFactory.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index 4b74208e798..bdf707d770e 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -608,6 +608,11 @@ int addSubEffect(cnode *root) return -EINVAL; } d = malloc(sizeof(effect_descriptor_t)); + if (!d) { + ALOGE("failed to allocate effect descriptor"); + return -EINVAL; + } + if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); @@ -692,8 +697,12 @@ int loadEffect(cnode *root) ALOGW("loadEffect() invalid uuid %s", node->value); return -EINVAL; } - d = malloc(sizeof(effect_descriptor_t)); + if (!d) { + ALOGE("failed to allocate effect descriptor"); + return -EINVAL; + } + if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); From 7910aa7022be092116bf2b07b4da6335d87e4d74 Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Mon, 11 Aug 2014 23:59:23 +0530 Subject: [PATCH 02/23] libstagefright: Handle INFO_FORMAT_CHANGED for dolby clips -For dolby clips when device is switched from headset to BT multiple times, media error is observed, and playback stops -When end device is changed, s/w Dolby decoder generates format change event which in certain condition leads to media error and playback stops -Make sure format change error is handled in AudioPlayer layer CRs-Fixed: 706801 Change-Id: I3ff3ef84b15ea5f9d3288215c1491dc30d17a413 --- media/libstagefright/AudioPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index 0a001619244..ba7678d5a7b 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -647,7 +647,7 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) { Mutex::Autolock autoLock(mLock); - if (err != OK) { + if (err != OK && err != INFO_FORMAT_CHANGED) { if (!mReachedEOS) { if (useOffload()) { // After seek there is a possible race condition if From ca1d49d92f4d416bf61cb761b87679fb741bc15d Mon Sep 17 00:00:00 2001 From: Li Sun Date: Tue, 22 Jul 2014 17:41:14 +0800 Subject: [PATCH 03/23] libstagefright: extend the interface to switch rtp transport - rtp transport can be changed by setting property "rtsp. transport.TCP" and udp is the first choice as default. But the property is the global variable and affects each instance's behaviour. Extend the interface of MyHandler to let each client make its own choice. If the client wants to choose tcp first, add the string/value "rtp.transport.TCP"/"true" in the headers when calling MediaPlayer.setDataSource. Change-Id: I19b6192da36d5c00e62c9f69de446f366f10c75c Crs-Fixed: 696569 --- media/libmediaplayerservice/nuplayer/RTSPSource.cpp | 11 +++++++++-- media/libmediaplayerservice/nuplayer/RTSPSource.h | 1 + media/libstagefright/rtsp/MyHandler.h | 8 ++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index aa0a53698ec..726f2ff6dc9 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -66,6 +66,13 @@ NuPlayer::RTSPSource::RTSPSource( mExtraHeaders.removeItemsAt(index); } + + index = mExtraHeaders.indexOfKey(String8("rtp.transport.TCP")); + + if (index >= 0) { + mFlags |= kFlagUseTCP; + mExtraHeaders.removeItemsAt(index); + } } } @@ -101,7 +108,7 @@ void NuPlayer::RTSPSource::prepareAsync() { mSDPLoader->load( mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); } else { - mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID); + mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID, (mFlags & kFlagUseTCP) ? true : false); mLooper->registerHandler(mHandler); mHandler->connect(); @@ -652,7 +659,7 @@ void NuPlayer::RTSPSource::onSDPLoaded(const sp &msg) { } else { sp notify = new AMessage(kWhatNotify, mReflector->id()); - mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID); + mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID, (mFlags & kFlagUseTCP) ? true : false); mLooper->registerHandler(mHandler); mHandler->loadSDP(desc); diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 849355ede06..1950d098f86 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -81,6 +81,7 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { enum Flags { // Don't log any URLs. kFlagIncognito = 1, + kFlagUseTCP = 2, }; struct TrackInfo { diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index f9c7fd53bfa..b1e57e181ce 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -102,7 +102,7 @@ struct MyHandler : public AHandler { MyHandler( const char *url, const sp ¬ify, - bool uidValid = false, uid_t uid = 0) + bool uidValid = false, uid_t uid = 0, bool tcptransport = false) : mNotify(notify), mUIDValid(uidValid), mUID(uid), @@ -122,7 +122,7 @@ struct MyHandler : public AHandler { mCheckPending(false), mCheckGeneration(0), mCheckTimeoutGeneration(0), - mTryTCPInterleaving(false), + mTryTCPInterleaving(tcptransport), mTryFakeRTCP(false), mReceivedFirstRTCPPacket(false), mReceivedFirstRTPPacket(false), @@ -138,10 +138,10 @@ struct MyHandler : public AHandler { PRIORITY_HIGHEST); char value[PROPERTY_VALUE_MAX] = {0}; - property_get("rtsp.transport.TCP", value, "false"); + property_get("rtsp.transport.TCP", value, "0"); if (!strcmp(value, "true")) { mTryTCPInterleaving = true; - } else { + } else if (!strcmp(value, "false")) { mTryTCPInterleaving = false; } From 44a6edf6c1e45fab17d309e9562dfffd0d4bd322 Mon Sep 17 00:00:00 2001 From: Patrik2 Carlsson Date: Fri, 17 Aug 2012 15:16:50 +0200 Subject: [PATCH 04/23] Support MPEG4 and H263 FourCC types in Matroska files Handles MPEG4 and H263 content with FourCC header in Matroska files based on how these are handled in the AVI parser. Also adding placehoders for DivX. Change-Id: I38b2c2fd429b6e4810a7b118bf60823d502320ae --- .../matroska/MatroskaExtractor.cpp | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 022205dc2a8..fec682cce4b 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -41,6 +41,20 @@ namespace android { +typedef struct { + uint32_t biSize; + uint32_t biWidth; + uint32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + uint32_t biXPelsPerMeter; + uint32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +} BITMAPINFOHEADER; + struct DataSourceReader : public mkvparser::IMkvReader { DataSourceReader(const sp &source) : mSource(source) { @@ -974,6 +988,49 @@ void MatroskaExtractor::addTracks() { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); } else if (!strcmp("V_VP9", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); + } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) { + if (codecPrivateSize >= sizeof(BITMAPINFOHEADER)) { + char *fourcc = (char *) &((BITMAPINFOHEADER *) codecPrivate)->biCompression; + + switch (FOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3])) { + case 'XVID': + case 'xvid': + case 'FMP4': + case 'fmp4': + case 'MP4V': + case 'mp4v': + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); + break; + case 'H263': + case 'h263': + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); + break; + case 'DIV3': + case 'div3': + case 'DIV4': + case 'div4': + ALOGW("DivX 3.11 codec not supported"); + continue; + case 'DIVX': + case 'divx': + ALOGW("DivX 4 codec not supported"); + continue; + case 'DX50': + case 'dx50': + ALOGW("DivX 5 codec not supported"); + continue; + case 'MP42': + default: + ALOGW("fourcc id: %hhX%hhX%hhX%hhX is not supported\n", + fourcc[0], fourcc[1], fourcc[2], fourcc[3]); + continue; + } + + ALOGV("fourcc id: %.4s", fourcc); + } else { + ALOGW("fourcc size: %d is not supported\n", codecPrivateSize); + continue; + } } else { ALOGW("%s is not supported.", codecID); continue; From b428fc094c5b9df06ba43ac2036789af6fb9f328 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 20 Oct 2014 00:23:46 -0700 Subject: [PATCH 05/23] stagefright: Fix crash if PCM offload gets a null source Change-Id: I4db08355fb132288cec2ba99ec4dcb77f1618add --- media/libstagefright/AwesomePlayer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index cc152d83856..0787554ed60 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1931,7 +1931,9 @@ status_t AwesomePlayer::initAudioDecoder() { mAudioSource = mAudioTrack; #ifndef QCOM_DIRECTTRACK } else { - mOmxSource->getFormat()->setInt32(kKeySampleBits, 16); + if (mOmxSource != NULL) { + mOmxSource->getFormat()->setInt32(kKeySampleBits, 16); + } mAudioSource = mOmxSource; #endif } From ea5d683a51d6931a200c8257c9e18150def79355 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 20 Oct 2014 02:43:09 -0700 Subject: [PATCH 06/23] media: Cleanup some unnecessary old code Change-Id: Id204180026b701bbf4c565c34a6fbba8b120eb0a --- media/libmedia/AudioRecord.cpp | 7 +------ media/libmedia/AudioTrack.cpp | 10 ---------- services/audioflinger/AudioMixer.cpp | 4 ---- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index e2d6985b9b2..ee40689d2e3 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -222,12 +222,7 @@ status_t AudioRecord::set( return BAD_VALUE; } mChannelMask = channelMask; - uint32_t channelCount = popcount(channelMask -#ifdef QCOM_HARDWARE - &(AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_5POINT1)); -#else - ); -#endif + uint32_t channelCount = popcount(channelMask); mChannelCount = channelCount; #ifdef QCOM_DIRECTTRACK diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 387d8f0b670..43f4da14314 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -196,16 +196,6 @@ AudioTrack::~AudioTrack() mAudioTrack.clear(); IPCThreadState::self()->flushCommands(); AudioSystem::releaseAudioSessionId(mSessionId); - if (isOffloaded()) { - char propValue[PROPERTY_VALUE_MAX]; - bool prop_enabled = false; - - if (property_get("audio.offload.multiple.enabled", propValue, NULL)) - prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); - - if (prop_enabled) - AudioSystem::releaseOutput(mOutput); - } #endif } } diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 64103e0b957..bfeb5133aac 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -564,11 +564,7 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) (value == 48000 && devSampleRate == 44100))) { quality = AudioResampler::LOW_QUALITY; } else { -#ifdef QCOM_HARDWARE - quality = AudioResampler::VERY_HIGH_QUALITY; -#else quality = AudioResampler::DEFAULT_QUALITY; -#endif } resampler = AudioResampler::create( format, From d52306987597cb1698ca1cadb95a5d12ea995423 Mon Sep 17 00:00:00 2001 From: "jin.seong" Date: Tue, 29 Apr 2014 15:53:18 +0900 Subject: [PATCH 07/23] Remove potential cause of underrun. 1. This part of ProcessAudioBuffer function can make underrun issue. Because AudioTrackThread::threadLoop's default case is 'pauseInternal'. 2. Without removed part : If AudioTrack obtain small buffer, then it can request small decoded data to player service without waiting. 3. We already have 'waiting codes' in 'AudioTrackshared.cpp ClientProxy::obtainBuffer', it using '__futex_syscall'. If we got 'full shared buffer', then 'ClientProxy::obtainBuffer' waits 'ServerProxy::releaseBuffer'. It means, there are duplicated 'waiting codes' for ProcessAudioBuffer. So I removed this part for preventing underrun issue. Change-Id: Idcca686054d92a4d123873b78b3b9c2e87d3bdca Signed-off-by: Jinhyuk Seong --- media/libmedia/AudioTrack.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 43f4da14314..d99e19a065e 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1882,16 +1882,6 @@ nsecs_t AudioTrack::processAudioBuffer(const sp& thread) return NS_NEVER; } - if (mRetryOnPartialBuffer && !isOffloaded()) { - mRetryOnPartialBuffer = false; - if (avail < mRemainingFrames) { - int64_t myns = ((mRemainingFrames - avail) * 1100000000LL) / sampleRate; - if (ns < 0 || myns < ns) { - ns = myns; - } - return ns; - } - } // Divide buffer size by 2 to take into account the expansion // due to 8 to 16 bit conversion: the callback must fill only half From fc4d7263a73057d7ed666861e4dd9e78d1af55c6 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 20 Oct 2014 02:53:37 -0700 Subject: [PATCH 08/23] Revert "libmedia: Add flag for non-native FAST tracks." * Changing design of this, no longer needed. This reverts commit a667d25f10063679829f3eca39d6d6d84d3ac05e. Change-Id: If8e348cdf53f01314a05fa4ea1a5dfdec6cc24ba --- media/libmedia/Android.mk | 4 ---- media/libmedia/AudioTrack.cpp | 2 -- services/audioflinger/Android.mk | 4 ---- services/audioflinger/Threads.cpp | 2 -- 4 files changed, 12 deletions(-) diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index c43ddb108c8..e8c2db26d15 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -86,10 +86,6 @@ ifeq ($(BOARD_USES_QCOM_HARDWARE),true) endif endif -ifneq ($(AUDIO_FEATURE_ENABLED_ULTRA_LOW_LATENCY),true) - LOCAL_CFLAGS += -DNATIVE_FAST_TRACKS_ONLY -endif - # for LOCAL_CFLAGS += -DANDROID_SMP=$(if $(findstring true,$(TARGET_CPU_SMP)),1,0) LOCAL_SRC_FILES += SingleStateQueue.cpp diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index d99e19a065e..c94f8724c23 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1135,13 +1135,11 @@ status_t AudioTrack::createTrack_l( } ALOGV("createTrack_l() output %d afLatency %d", output, afLatency); -#ifdef NATIVE_FAST_TRACKS_ONLY if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) { ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)", sampleRate, afSampleRate); flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST); } -#endif // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where // n = 1 fast track with single buffering; nBuffering is ignored diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 86940253365..08bdeab2f68 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -93,10 +93,6 @@ ifeq ($(strip $(BOARD_USE_RESAMPLER_IN_PCM_OFFLOAD_PATH)),true) LOCAL_CFLAGS += -DENABLE_RESAMPLER_IN_PCM_OFFLOAD_PATH endif -ifneq ($(AUDIO_FEATURE_ENABLED_ULTRA_LOW_LATENCY),true) -LOCAL_CFLAGS += -DNATIVE_FAST_TRACKS_ONLY -endif - # Define ANDROID_SMP appropriately. Used to get inline tracing fast-path. ifeq ($(TARGET_CPU_SMP),true) LOCAL_CFLAGS += -DANDROID_SMP=1 diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index f5aa5713562..c92eeb257c3 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1289,10 +1289,8 @@ sp AudioFlinger::PlaybackThread::createTrac // mono or stereo ( (channelMask == AUDIO_CHANNEL_OUT_MONO) || (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) && -#ifdef NATIVE_FAST_TRACKS_ONLY // hardware sample rate (sampleRate == mSampleRate) && -#endif // normal mixer has an associated fast mixer hasFastMixer() && // there are sufficient fast track slots available From c7ea3d0e41671d951d4558dda754e54f0deb2d42 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 22 Oct 2014 14:43:57 -0700 Subject: [PATCH 09/23] Revert "stagefright: Disable HSR for now" * Adding support for HSR on new chips. This reverts commit 23373ed880fc124f20a6ee90e539576ffbfddba8. Change-Id: I468498e72bae874184bdbb85cbc92c735365b403 --- media/libstagefright/ExtendedUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/ExtendedUtils.cpp b/media/libstagefright/ExtendedUtils.cpp index 587f4cfd15b..894e743b1c4 100644 --- a/media/libstagefright/ExtendedUtils.cpp +++ b/media/libstagefright/ExtendedUtils.cpp @@ -80,7 +80,7 @@ void ExtendedUtils::HFR::setHFRIfEnabled( hfr = 0; } -#if 0 +#ifndef LEGACY_MEDIA const char *hsr_str = params.get("video-hsr"); if(hsr_str && !strncmp(hsr_str,"on",2)) { @@ -96,7 +96,7 @@ status_t ExtendedUtils::HFR::initializeHFR( int64_t &maxFileDurationUs, video_encoder videoEncoder) { status_t retVal = OK; -#if 0 +#ifndef LEGACY_MEDIA //Check HSR first, if HSR is enable set HSR to kKeyFrameRate int32_t hsr =0; if (meta->findInt32(kKeyHSR, &hsr)) { From 869cfa7f954cdedc44a9b248ab569fbbbf630ce1 Mon Sep 17 00:00:00 2001 From: vivek mehta Date: Thu, 6 Mar 2014 14:10:30 -0800 Subject: [PATCH 10/23] libstagefright: HSR: Read framerate from HSR key - HSR and HFR keys are made mutually exclusive now. - In case of HSR, HSR key will be set with requested frame rate and HFR key is not set. - In case of HFR, HFR key will be set with requested frame rate and HSR key is not set. - Check if video-hfr key is set set kKeyHFR with HFR key value passed by camera else check video-hsr key, if set set kKeyHSR with HSR key value passed by camera Change-Id: Ic7ad098137812ad78afdc326334fa390404075fc --- media/libstagefright/ExtendedUtils.cpp | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/ExtendedUtils.cpp b/media/libstagefright/ExtendedUtils.cpp index 894e743b1c4..17fbb22e083 100644 --- a/media/libstagefright/ExtendedUtils.cpp +++ b/media/libstagefright/ExtendedUtils.cpp @@ -74,21 +74,29 @@ void ExtendedUtils::HFR::setHFRIfEnabled( int32_t hfr = -1; if ( hfr_str != NULL ) { hfr = atoi(hfr_str); - } - if (hfr < 0) { - ALOGW("Invalid hfr value(%d) set from app. Disabling HFR.", hfr); - hfr = 0; + if(hfr > 0) { + ALOGI("HFR enabled, %d value provided", hfr); + meta->setInt32(kKeyHFR, hfr); + return; + } else { + ALOGI("Invalid hfr value(%d) set from app. Disabling HFR.", hfr); + } } #ifndef LEGACY_MEDIA const char *hsr_str = params.get("video-hsr"); - - if(hsr_str && !strncmp(hsr_str,"on",2)) { - ALOGI("HSR [%d] ON",hfr); - meta->setInt32(kKeyHSR, hfr); - } else + int32_t hsr = -1; + if(hsr_str != NULL ) { + hsr = atoi(hsr_str); + if(hsr > 0) { + ALOGI("HSR enabled, %d value provided", hsr); + meta->setInt32(kKeyHSR, hsr); + return; + } else { + ALOGI("Invalid hsr value(%d) set from app. Disabling HSR.", hsr); + } + } #endif - meta->setInt32(kKeyHFR, hfr); } status_t ExtendedUtils::HFR::initializeHFR( From d480ab07b1934f060e81585c6d55508d353e8cd5 Mon Sep 17 00:00:00 2001 From: Srinu Gorle Date: Fri, 20 Jun 2014 11:37:48 +0530 Subject: [PATCH 11/23] libstagefright: use appropriate hevc decoder on 8916 and 8939 8916 supports HEVC software decoder and 8939 support h/w decoder. Based on media.swhevccodectype and media.hwhevccodectype properties values instantiate appropriate HEVC decoder. Change-Id: Ic3d37e6184db256f4d83bfe74b67271b20f94ec0 --- include/media/stagefright/ExtendedCodec.h | 8 ++++++++ media/libstagefright/ExtendedCodec.cpp | 21 +++++++++++++++++++++ media/libstagefright/OMXCodec.cpp | 8 +++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/media/stagefright/ExtendedCodec.h b/include/media/stagefright/ExtendedCodec.h index 5ec73a78ac2..5cedee27d74 100644 --- a/include/media/stagefright/ExtendedCodec.h +++ b/include/media/stagefright/ExtendedCodec.h @@ -56,6 +56,12 @@ struct ExtendedCodec { kPortIndexInput = 0, kPortIndexOutput = 1 }; + + enum kHEVCCodecType{ + kCodecType_None, + kCodecType_SWHEVC, + kCodecType_HWHEVC + }; static status_t convertMetaDataToMessage( const sp &meta, sp *format); @@ -145,6 +151,8 @@ struct ExtendedCodec { static bool useHWAACDecoder(const char *mime, int channelCount); + static kHEVCCodecType useHEVCDecoder(const char *mime); + static bool isSourcePauseRequired(const char *componentName); #if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS) diff --git a/media/libstagefright/ExtendedCodec.cpp b/media/libstagefright/ExtendedCodec.cpp index 15cf12f59bf..b52da1bd1c4 100644 --- a/media/libstagefright/ExtendedCodec.cpp +++ b/media/libstagefright/ExtendedCodec.cpp @@ -1228,6 +1228,24 @@ bool ExtendedCodec::useHWAACDecoder(const char *mime, int channelCount) { return false; } +ExtendedCodec::kHEVCCodecType ExtendedCodec::useHEVCDecoder(const char *mime) { + char value[PROPERTY_VALUE_MAX] = {0}; + int sw_codectype = 0, hw_codectype = 0; + if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { + sw_codectype = property_get("media.swhevccodectype", value, NULL); + if (sw_codectype && !strncmp("1", value, 1)) { + ALOGI("Using SW HEVC Decoder"); + return ExtendedCodec::kCodecType_SWHEVC; + } + hw_codectype = property_get("media.hwhevccodectype", value, NULL); + if (hw_codectype && !strncmp("1", value, 1)) { + ALOGI("Using HW HEVC Decoder"); + return ExtendedCodec::kCodecType_HWHEVC; + } + } + return ExtendedCodec::kCodecType_None; +} + bool ExtendedCodec::isSourcePauseRequired(const char *componentName) { /* pause is required for hardware component to release adsp resources */ if (!strncmp(componentName, "OMX.qcom.", 9)) { @@ -1392,6 +1410,9 @@ bool ExtendedCodec::isSourcePauseRequired(const char *componentName) { return false; } + ExtendedCodec::kHEVCCodecType ExtendedCodec::useHEVCDecoder(const char *mime) { + return ExtendedCodec::kCodecType_None; + } void ExtendedCodec::enableSmoothStreaming( const sp &omx, IOMX::node_id nodeID, bool* isEnabled, const char* componentName) { diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 71f6f8d7b45..f21a778093f 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -460,10 +460,10 @@ sp OMXCodec::Create( const char *mime; bool success = meta->findCString(kKeyMIMEType, &mime); CHECK(success); - Vector matchingCodecs; #ifdef QCOM_HARDWARE + ExtendedCodec::kHEVCCodecType hevc_codectype = ExtendedCodec::useHEVCDecoder(mime); int channelCount = 0; int trackId = 0; meta->findInt32(kKeyChannelCount, &channelCount); @@ -472,6 +472,12 @@ sp OMXCodec::Create( && trackId > 1) { findMatchingCodecs(mime, createEncoder, "OMX.qcom.audio.decoder.multiaac", flags, &matchingCodecs); + } else if (hevc_codectype == ExtendedCodec::kCodecType_SWHEVC) { + findMatchingCodecs(mime, createEncoder, + "OMX.qcom.video.decoder.hevcswvdec", flags, &matchingCodecs); + } else if (hevc_codectype == ExtendedCodec::kCodecType_HWHEVC) { + findMatchingCodecs(mime, createEncoder, + "OMX.qcom.video.decoder.hevc", flags, &matchingCodecs); } else { #endif findMatchingCodecs( From 7c84b932748a45f550d076307cd31abf84871415 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 27 Oct 2014 12:32:47 -0700 Subject: [PATCH 12/23] camera: Always enable preview metadata * Remove the ifdefs which enable/disable the preview metadata during start/stop preview. This causes issues with face detection and other uses on new hardware. * I am not aware of any hardware which still needs this. Change-Id: I3dd0941a61affb4862a2e8f4f0c2cf59c95b150e --- .../camera/libcameraservice/api1/CameraClient.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 67d40597447..1629e05af28 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -89,9 +89,7 @@ status_t CameraClient::initialize(camera_module_t *module) { // Enable zoom, error, focus, and metadata messages by default enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS -#ifndef CAMERA_MSG_MGMT | CAMERA_MSG_PREVIEW_METADATA -#endif #ifndef OMAP_ICS_CAMERA | CAMERA_MSG_FOCUS_MOVE #endif @@ -362,9 +360,6 @@ status_t CameraClient::setPreviewCallbackTarget( // start preview mode status_t CameraClient::startPreview() { Mutex::Autolock lock(mLock); -#ifdef CAMERA_MSG_MGMT - enableMsgType(CAMERA_MSG_PREVIEW_METADATA); -#endif LOG1("startPreview (pid %d)", getCallingPid()); return startCameraMode(CAMERA_PREVIEW_MODE); } @@ -457,9 +452,6 @@ status_t CameraClient::startRecordingMode() { void CameraClient::stopPreview() { LOG1("stopPreview (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); -#ifdef CAMERA_MSG_MGMT - disableMsgType(CAMERA_MSG_PREVIEW_METADATA); -#endif if (checkPidAndHardware() != NO_ERROR) return; #ifdef OMAP_ENHANCEMENT @@ -596,9 +588,6 @@ status_t CameraClient::takePicture(int msgType) { #if defined(OMAP_ICS_CAMERA) || defined(OMAP_ENHANCEMENT_BURST_CAPTURE) picMsgType |= CAMERA_MSG_COMPRESSED_BURST_IMAGE; -#endif -#ifdef CAMERA_MSG_MGMT - disableMsgType(CAMERA_MSG_PREVIEW_METADATA); #endif enableMsgType(picMsgType); #ifdef QCOM_HARDWARE From 9a1c61cde380e62f137b22c518ac00b01d7309c5 Mon Sep 17 00:00:00 2001 From: Jia Meng Date: Thu, 16 Oct 2014 15:20:41 +0800 Subject: [PATCH 13/23] stagefright: Avoid querying time from AudioPlayer after audio EOS If a clip's audio track is shorter than its video track, the system clock is used as the time source after audio EOS. However AwesomePlayer continues to query the media time from AudioPlayer within onVideoLagUpdate. This may take longer than the expected onVideoEvent interval of 20 ms which can cause delayed or dropped frames. Additionally, if onVideoEvent is more than 500 ms late, AwesomePlayer triggers a video-only seek to the incorrect audio EOS media time. Since the system clock continues to tick, video becomes even later after seek and seek is triggered again, resulting in a continuous seek. Stop querying the media time from AudioPlayer after audio EOS to avoid this scenario. Change-Id: I5c56a51509f8787d384696c703a9327b0fa5dbac CRs-Fixed: 739308 --- media/libstagefright/AwesomePlayer.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 0787554ed60..4b494bdeb68 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -805,16 +805,18 @@ void AwesomePlayer::onVideoLagUpdate() { } mVideoLagEventPending = false; - int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs(); - int64_t videoLateByUs = audioTimeUs - mVideoTimeUs; + if (!(mFlags & AUDIO_AT_EOS)) { + int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs(); + int64_t videoLateByUs = audioTimeUs - mVideoTimeUs; - if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) { - ALOGV("video late by %lld ms.", videoLateByUs / 1000ll); + if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) { + ALOGV("video late by %lld ms.", videoLateByUs / 1000ll); - notifyListener_l( - MEDIA_INFO, - MEDIA_INFO_VIDEO_TRACK_LAGGING, - videoLateByUs / 1000ll); + notifyListener_l( + MEDIA_INFO, + MEDIA_INFO_VIDEO_TRACK_LAGGING, + videoLateByUs / 1000ll); + } } postVideoLagEvent_l(); @@ -2431,6 +2433,7 @@ void AwesomePlayer::onVideoEvent() { } if (latenessUs > 500000ll + && !(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL && mAudioPlayer->getMediaTimeMapping( &realTimeUs, &mediaTimeUs)) { From 9a0de063d08a13b5fc4591e0c7fb96d192f09cbc Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Wed, 8 Oct 2014 10:48:17 +0100 Subject: [PATCH 14/23] surfacemediasource: Do not assume that onBuffersReleased means EOS When using a surface media source the callee may release/allocate buffers, for instance when negotiating formats with an external source. This means that onBuffersReleased might be called but that does not mean that there isn't a producer in the other end, just that it might have changed formats. This patch solves that by if-deffing a CAF addition that makes wifi-display non-functional in some devices. Change-Id: Ie702c1b4b32f0b00388beea9cf2ff032a50b0bdb --- media/libstagefright/SurfaceMediaSource.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index e8402ad342e..3a8d7557ff7 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -469,7 +469,9 @@ void SurfaceMediaSource::onBuffersReleased() { Mutex::Autolock lock(mMutex); +#ifdef QCOM_HARDWARE mBuffersReleased = true; +#endif mFrameAvailableCondition.signal(); for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { From 85f55f69f4a1d4311d30145e7aaa6923c7ab71c6 Mon Sep 17 00:00:00 2001 From: Divya Narayanan Poojary Date: Thu, 12 Jun 2014 14:14:18 +0530 Subject: [PATCH 15/23] audio: handle events properly in AudioOutput::CallbackWrapper() - MediaPlayerService::AudioOutput::CallbackWrapper() can't handle AudioTrack::EVENT_STREAM_END and AudioTrack::EVENT_NEW_IAUDIOTRACK - Fix is to handle the events separately. Change-Id: I986ce8d859dced19fa0bc82acb180fbd11417ca9 CRs-Fixed: 678573 --- .../MediaPlayerService.cpp | 121 +++--------------- 1 file changed, 21 insertions(+), 100 deletions(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 8d46b1919bc..671055040c1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1852,102 +1852,6 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) } // static -#ifdef QCOM_DIRECTTRACK -void MediaPlayerService::AudioOutput::CallbackWrapper( - int event, void *cookie, void *info) { - //ALOGV("callbackwrapper"); - if (event == AudioTrack::EVENT_UNDERRUN) { - ALOGW("Event underrun"); - CallbackData *data = (CallbackData*)cookie; - data->lock(); - AudioOutput *me = data->getOutput(); - if (me == NULL) { - // no output set, likely because the track was scheduled to be reused - // by another player, but the format turned out to be incompatible. - data->unlock(); - return; - } - ALOGD("Callback!!!"); - (*me->mCallback)( - me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie, CB_EVENT_UNDERRUN); - data->unlock(); - return; - } - if (event == AudioTrack::EVENT_HW_FAIL) { - ALOGW("Event hardware failure"); - CallbackData *data = (CallbackData*)cookie; - if (data != NULL) { - data->lock(); - AudioOutput *me = data->getOutput(); - if (me == NULL) { - // no output set, likely because the track was - // scheduled to be reused - // by another player, but the format turned out - // to be incompatible. - data->unlock(); - return; - } - ALOGV("Callback!!!"); - (*me->mCallback)(me, NULL, (size_t)AudioTrack::EVENT_HW_FAIL, - me->mCallbackCookie, CB_EVENT_HW_FAIL); - data->unlock(); - } - return; - } - if (event == AudioTrack::EVENT_MORE_DATA) { - CallbackData *data = (CallbackData*)cookie; - data->lock(); - AudioOutput *me = data->getOutput(); - AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; - if (me == NULL) { - // no output set, likely because the track was scheduled to be reused - // by another player, but the format turned out to be incompatible. - data->unlock(); - if (buffer != NULL) { - buffer->size = 0; - } - return; - } - - switch(event) { - case AudioTrack::EVENT_MORE_DATA: { - size_t actualSize = (*me->mCallback)( - me, buffer->raw, buffer->size, me->mCallbackCookie, - CB_EVENT_FILL_BUFFER); - - if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) { - // We've reached EOS but the audio track is not stopped yet, - // keep playing silence. - - memset(buffer->raw, 0, buffer->size); - actualSize = buffer->size; - } - - buffer->size = actualSize; - } break; - - - case AudioTrack::EVENT_STREAM_END: - ALOGV("callbackwrapper: deliver EVENT_STREAM_END"); - (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, - me->mCallbackCookie, CB_EVENT_STREAM_END); - break; - - case AudioTrack::EVENT_NEW_IAUDIOTRACK : - ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN"); - (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, - me->mCallbackCookie, CB_EVENT_TEAR_DOWN); - break; - - default: - ALOGE("received unknown event type: %d inside CallbackWrapper !", event); - } - - data->unlock(); - } - return; -} -#else void MediaPlayerService::AudioOutput::CallbackWrapper( int event, void *cookie, void *info) { //ALOGV("callbackwrapper"); @@ -1966,13 +1870,31 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( } switch(event) { +#ifdef QCOM_DIRECTTRACK + case AudioTrack::EVENT_UNDERRUN: + ALOGW("Event underrun"); + (*me->mCallback)( + me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie, CB_EVENT_UNDERRUN); + break; + + case AudioTrack::EVENT_HW_FAIL: + ALOGW("Event hardware failure"); + (*me->mCallback)(me, NULL, (size_t)AudioTrack::EVENT_HW_FAIL, + me->mCallbackCookie, CB_EVENT_HW_FAIL); + break; +#endif + case AudioTrack::EVENT_MORE_DATA: { size_t actualSize = (*me->mCallback)( me, buffer->raw, buffer->size, me->mCallbackCookie, CB_EVENT_FILL_BUFFER); - if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL && - (me->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) { + if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL +#ifndef QCOM_DIRECTTRACK + && (me->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) { +#else + ) { +#endif // We've reached EOS but the audio track is not stopped yet, // keep playing silence. @@ -1989,7 +1911,7 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( me->mCallbackCookie, CB_EVENT_STREAM_END); break; - case AudioTrack::EVENT_NEW_IAUDIOTRACK : + case AudioTrack::EVENT_NEW_IAUDIOTRACK: ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN"); (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, me->mCallbackCookie, CB_EVENT_TEAR_DOWN); @@ -2001,7 +1923,6 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( data->unlock(); } -#endif int MediaPlayerService::AudioOutput::getSessionId() const { From e305b6ec61fde6d0575a68280101904056f3ef41 Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Thu, 30 Oct 2014 20:39:41 -0700 Subject: [PATCH 16/23] camera: Allow hardware/camera.h header to be overridden Change-Id: I715ba261de0b01e61cbfe7cacd567a9f511fb8cb --- services/camera/libcameraservice/CameraService.h | 2 +- .../camera/libcameraservice/device1/CameraHardwareInterface.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 1864fbb2ec1..67f27ee8179 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include "hardware/camera.h" #include #include diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h index 6d051273b59..7e71c87017c 100644 --- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h +++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include "hardware/camera.h" #ifdef USE_MEMORY_HEAP_ION #include #endif From 0c0ab8010f529c1df6e61ed226823b7b89c066c6 Mon Sep 17 00:00:00 2001 From: Satya Krishna Pindiproli Date: Fri, 10 Jan 2014 16:41:51 +0530 Subject: [PATCH 17/23] 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 --- media/libmedia/Android.mk | 2 +- media/libstagefright/ACodec.cpp | 5 + media/libstagefright/Android.mk | 9 + media/libstagefright/AudioPlayer.cpp | 4 + media/libstagefright/ExtendedMediaDefs.cpp | 4 + media/libstagefright/FLACDecoder.cpp | 311 +++++++++++++++++++++ media/libstagefright/NuMediaExtractor.cpp | 24 +- media/libstagefright/OMXCodec.cpp | 37 ++- media/libstagefright/Utils.cpp | 16 ++ media/libstagefright/include/FLACDecoder.h | 90 ++++++ services/audioflinger/Android.mk | 2 +- 11 files changed, 486 insertions(+), 18 deletions(-) create mode 100644 media/libstagefright/FLACDecoder.cpp create mode 100644 media/libstagefright/include/FLACDecoder.h diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index e8c2db26d15..c3964e34cf2 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 a3d54a47c36..48503be3654 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 7ee91ec3221..b1f1246016e 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -154,6 +154,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 ba7678d5a7b..dc20fb12da1 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 92b8e581f53..4ddb8d387d1 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 00000000000..78faf0ae9ef --- /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 +#include + +#include +#include +#include +#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 &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 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 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 7bc7da24251..c263d244d07 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 #include @@ -275,24 +278,29 @@ status_t NuMediaExtractor::selectTrack(size_t index) { return OK; } } - sp 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 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 f21a778093f..7baede4be70 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 #endif +#ifdef QTI_FLAC_DECODER +#include "include/FLACDecoder.h" +#endif + namespace android { #ifdef USE_SAMSUNG_COLORFORMAT @@ -120,9 +124,14 @@ static sp Make##name(const sp &source, const sp InstantiateSoftwareEncoder( @@ -146,7 +155,7 @@ static sp InstantiateSoftwareEncoder( return NULL; } -#ifdef QCOM_DIRECTTRACK +#if defined(QCOM_DIRECTTRACK) || defined (QTI_FLAC_DECODER) static sp InstantiateSoftwareDecoder( const char *name, const sp &source) { struct FactoryInfo { @@ -154,7 +163,12 @@ static sp InstantiateSoftwareDecoder( sp (*CreateFunc)(const sp &); }; 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 InstantiateSoftwareDecoder( return NULL; } #endif + #undef FACTORY_CREATE_ENCODER #undef FACTORY_REF @@ -509,14 +524,20 @@ sp OMXCodec::Create( componentName = tmp.c_str(); } + sp softwareCodec; if (createEncoder) { - sp 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 2313a161611..cc448143888 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -509,6 +509,7 @@ status_t sendMetaDataToHal(sp& 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& 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 00000000000..2d14347b612 --- /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 +#include + +#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 &source); + ~FLACDecoder(); + void init(); + virtual status_t start(MetaData *params); + virtual status_t stop(); + virtual sp getFormat(); + virtual status_t read(MediaBuffer **buffer, const ReadOptions *options); + +private: + sp mSource; + sp 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 08bdeab2f68..d0b712d9f74 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 From 7babd71b912f0b26f9fa4d43f41f25af455b773e Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 2 Nov 2014 00:52:13 -0700 Subject: [PATCH 18/23] stagefright: Don't expose QTIFLAC definition unless enabled Change-Id: Ia3173ddc6adeff37b77bfe6b73e62702a3f178dc --- media/libstagefright/Utils.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index cc448143888..d43f5af9b18 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -576,7 +576,9 @@ 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 }, +#ifdef QTI_FLAC_DECODER { MEDIA_MIMETYPE_CONTAINER_QTIFLAC, AUDIO_FORMAT_FLAC }, +#endif #endif { 0, AUDIO_FORMAT_INVALID } }; From 2698376cdc1e3d0c3cda396e8cb08e0f37b71409 Mon Sep 17 00:00:00 2001 From: Li Sun Date: Fri, 26 Sep 2014 16:01:56 +0800 Subject: [PATCH 19/23] NuPlayer: use video hardware codec only - if the client has the specific request, only use video hardware codec for nuplayer Change-Id: Id6dd13b99d02ea4466f2014e0e4b3ff9b3f7e492 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 12 +++++++++++- media/libmediaplayerservice/nuplayer/NuPlayer.h | 2 ++ media/libstagefright/ACodec.cpp | 8 ++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 7df93033622..51a2d9ff4eb 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -161,7 +161,8 @@ NuPlayer::NuPlayer() mNumFramesDropped(0ll), mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), mStarted(false), - mSeeking(false) { + mSeeking(false), + isCodecSpecific(false) { } NuPlayer::~NuPlayer() { @@ -216,6 +217,13 @@ void NuPlayer::setDataSourceAsync( sp notify = new AMessage(kWhatSourceNotify, id()); + if (headers) { + ssize_t index = headers->indexOfKey(String8("codecspecific")); + if (index >= 0) { + isCodecSpecific = true; + } + } + sp source; if (IsHTTPLiveURL(url)) { source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID); @@ -922,6 +930,8 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp *decoder) { AString mime; CHECK(format->findString("mime", &mime)); mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); + if(isCodecSpecific) + format->setInt32("hardwarecodecOnly", 1); } sp notify = diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index c7d83629801..9c6fdfe195f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -160,6 +160,8 @@ struct NuPlayer : public AHandler { bool mStarted; bool mSeeking; + bool isCodecSpecific; + status_t instantiateDecoder(bool audio, sp *decoder); status_t feedDecoderInputData(bool audio, const sp &msg); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 48503be3654..8688501ff67 100755 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -3734,7 +3734,11 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp &msg) { // about any notifications in the afterlife. mDeathNotifier.clear(); } - + int32_t hardwarecodecOnly = 0; + if (msg->findInt32("hardwarecodecOnly", &hardwarecodecOnly) + && hardwarecodecOnly == 1) { + ALOGV("use hardware codec only"); + } Vector matchingCodecs; AString mime; @@ -3769,7 +3773,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp &msg) { mime.c_str(), encoder, // createEncoder NULL, // matchComponentName - 0, // flags + hardwarecodecOnly ? OMXCodec::kHardwareCodecsOnly : 0, // flags &matchingCodecs); } From c3a33d9732e8a6bf9ee6f0ed3b344494033e1a9b Mon Sep 17 00:00:00 2001 From: Praveen Chavan Date: Fri, 22 Nov 2013 12:55:01 -0800 Subject: [PATCH 20/23] stagefright: add an extra buffer to ANW's BUfferQueue Add an extra buffer to ensure video player has a free buffer to dequeue rather than wait for the queued buffer to be displayed. Enable logs to indicate number of buffers allocated. NOTE: This is not needed for 30fps content on 60fps panel, But making this change regardless for all framerates till root-cause is identified in SF Change-Id: Id1048d7a104b2a75613dda8b9cf166e59bc4bb04 stagefright: ACodec: add an extra buffer to ANW's BUfferQueue Add an extra min-undequeued buffer to ensure framework (ACodec) has a free buffer to dequeue rather than wait for the queued buffer to be displayed This improves the performance of playback via nuPlayer. Change-Id: If02a91f8121b7a2664c0264498c7b7e3031a88d7 CRs-Fixed: 607794 stagefright: Increase buffers with nativewindow To avoid frame-drops due to latencies in rendering. If (minUnDequeued) buffers are caught in display pipeline, dequeueBuffer will block, which delays subsequent queuebuffer, and this repeats until a buffer is canceled (frame drop). This issue is more prominent with high resolution content on secondary displays. Adding additional buffers increases the stagger in display and makes finding a free buffer more likely Change-Id: I352a77ffcd67c8fdd1c2485e3737ba923950f8fd CRs-Fixed: 714475 --- media/libstagefright/ACodec.cpp | 8 ++++++++ media/libstagefright/OMXCodec.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 8688501ff67..3ff1a63a792 100755 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -663,6 +663,14 @@ status_t ACodec::configureOutputBuffersFromNativeWindow( return err; } +#ifdef QCOM_HARDWARE + //add an extra buffer to display queue to get around dequeue+wait + //blocking too long (more than 1 Vsync) in case BufferQeuue is in + //sync-mode and advertizes only 1 buffer + (*minUndequeuedBuffers)++; + ALOGI("NOTE: Overriding minUndequeuedBuffers to %lu",*minUndequeuedBuffers); +#endif + // XXX: Is this the right logic to use? It's not clear to me what the OMX // buffer counts refer to - how do they account for the renderer holding on // to buffers? diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 7baede4be70..8aeeed378c5 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -2426,12 +2426,23 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { return err; } +#ifdef QCOM_HARDWARE + // Add extra buffer to display queue to get around dequeue+wait + // blocking too long in case BufferQueue is in sync-mode and advertises + // only 1 buffer. Also, restrict to 2 extra buffers for > 1080p + minUndequeuedBufs += + (def.format.video.nFrameWidth * def.format.video.nFrameHeight > 1088 * 1920) + ? 2 : 3; + ALOGI("NOTE: Overriding minUndequeuedBufs to %d",minUndequeuedBufs); +#endif + // XXX: Is this the right logic to use? It's not clear to me what the OMX // buffer counts refer to - how do they account for the renderer holding on // to buffers? if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; def.nBufferCountActual = newBufferCount; + ALOGI("NOTE: Allocating %lu buffers on output port",def.nBufferCountActual); err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); if (err != OK) { From d7165d776a1bd22c5837514960e009f075051c79 Mon Sep 17 00:00:00 2001 From: Anders3 Petersson Date: Thu, 30 Jan 2014 07:35:54 +0100 Subject: [PATCH 21/23] Solved problem with hanging decode call Improved error handling in Mediaplayer service, stops decode from hanging when player->start() fails. Change-Id: Ia160ff6eb9aeef0971c004e8baa90750e5636479 --- media/libmediaplayerservice/MediaPlayerService.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 671055040c1..fce58e7bc79 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1214,6 +1214,7 @@ status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* ALOGV("decode(%s)", url); sp player; status_t status = BAD_VALUE; + status_t err = OK; // Protect our precious, precious DRMd ringtones by only allowing // decoding of http, but not filesystem paths or content Uris. @@ -1246,7 +1247,11 @@ status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* if (cache->wait() != NO_ERROR) goto Exit; ALOGV("start"); - player->start(); + err = player->start(); + if (err != NO_ERROR) { + ALOGE("Error: %d Starting player in decode", err); + goto Exit; + } ALOGV("wait for playback complete"); cache->wait(); @@ -1276,6 +1281,7 @@ status_t MediaPlayerService::decode(int fd, int64_t offset, int64_t length, ALOGV("decode(%d, %lld, %lld)", fd, offset, length); sp player; status_t status = BAD_VALUE; + status_t err = OK; player_type playerType = MediaPlayerFactory::getPlayerType(NULL /* client */, fd, @@ -1301,7 +1307,11 @@ status_t MediaPlayerService::decode(int fd, int64_t offset, int64_t length, if (cache->wait() != NO_ERROR) goto Exit; ALOGV("start"); - player->start(); + err = player->start(); + if (err != NO_ERROR) { + ALOGE("Error: %d Starting player in decode", err); + goto Exit; + } ALOGV("wait for playback complete"); cache->wait(); From c4a1f51e0bb8cc3b136ef7dfb6e37c27d546a10d Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 24 Oct 2014 09:09:56 -0700 Subject: [PATCH 22/23] stagefright: Query PCM output format and fix bugs * Ask the decoder about it's PCM output format instead of hardcoding exceptions. * Google's AAC codec fails on main profile, skip it. * Don't crash on unsupported Windows Media files. Change-Id: I2bfe19993e8b0cf7ff78b6d4b63465be093ae1d0 --- include/media/stagefright/OMXCodec.h | 2 ++ media/libstagefright/OMXCodec.cpp | 54 ++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index b3920424510..9b7a6568417 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -320,6 +320,8 @@ struct OMXCodec : public MediaSource, status_t setDTSFormat(const sp &inputFormat); status_t setFFmpegAudioFormat(const sp &inputFormat); + status_t getPCMOutputFormat(const sp &meta); + status_t allocateBuffers(); status_t allocateBuffersOnPort(OMX_U32 portIndex); #ifdef USE_SAMSUNG_COLORFORMAT diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 8aeeed378c5..269028a88d9 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -798,10 +798,16 @@ status_t OMXCodec::configureCodec(const sp &meta) { CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); - if (!meta->findInt32(kKeyAACProfile, &aacProfile)) { + if (!meta->findInt32(kKeyAACAOT, &aacProfile)) { aacProfile = OMX_AUDIO_AACObjectNull; } + // Google's AAC decoder can't handle MAIN profile + if (!strncmp(mComponentName, "OMX.google.", 11) && + aacProfile == OMX_AUDIO_AACObjectMain) { + return ERROR_UNSUPPORTED; + } + int32_t isADTS; if (!meta->findInt32(kKeyIsADTS, &isADTS)) { isADTS = false; @@ -887,12 +893,6 @@ status_t OMXCodec::configureCodec(const sp &meta) { CODEC_LOGE("setAC3Format() failed (err = %d)", err); return err; } -#ifdef ENABLE_AV_ENHANCEMENTS - // FFMPEG will convert floating point to 24-bit PCM - if (ExtendedUtils::isHiresAudioEnabled()) { - meta->setInt32(kKeySampleBits, 24); - } -#endif } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_APE, mMIME)) { status_t err = setAPEFormat(meta); if (err != OK) { @@ -905,12 +905,6 @@ status_t OMXCodec::configureCodec(const sp &meta) { CODEC_LOGE("setDTSFormat() failed (err = %d)", err); return err; } -#ifdef ENABLE_AV_ENHANCEMENTS - // FFMPEG will convert DTS floating point to 24-bit PCM - if (ExtendedUtils::isHiresAudioEnabled()) { - meta->setInt32(kKeySampleBits, 24); - } -#endif } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_FFMPEG, mMIME)) { status_t err = setFFmpegAudioFormat(meta); if (err != OK) { @@ -918,6 +912,8 @@ status_t OMXCodec::configureCodec(const sp &meta) { return err; } } + getPCMOutputFormat(meta); + meta->dumpToLog(); #ifdef QCOM_HARDWARE } else { if (!mIsVideo && mIsEncoder) { @@ -4398,6 +4394,28 @@ status_t OMXCodec::setFFmpegVideoFormat(const sp &meta) return err; } +status_t OMXCodec::getPCMOutputFormat(const sp &meta) +{ + int32_t bitsPerSample = 16; + status_t err = OK; + + OMX_AUDIO_PARAM_PCMMODETYPE params; + InitOMXParams(¶ms); + params.nPortIndex = kPortIndexOutput; + + err = mOMX->getParameter( + mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); + + if (err == OK) { + ALOGI(" nSamplingRate = %ld\n", params.nSamplingRate); + ALOGI(" nChannels = %ld\n", params.nChannels); + ALOGI(" nBitPerSample = %ld\n", params.nBitPerSample); + + meta->setInt32(kKeySampleBits, params.nBitPerSample); + } + return err; +} + //audio status_t OMXCodec::setMP3Format(const sp &meta) { @@ -4465,7 +4483,13 @@ status_t OMXCodec::setWMAFormat(const sp &meta) CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); CHECK(meta->findInt32(kKeyBitRate, &bitRate)); - CHECK(meta->findInt32(kKeyBlockAlign, &blockAlign)); + if (!meta->findInt32(kKeyBlockAlign, &blockAlign)) { + // we should be last on the codec list, but another sniffer may + // have handled it and there is no hardware codec. + if (!meta->findInt32(kKeyWMABlockAlign, &blockAlign)) { + return ERROR_UNSUPPORTED; + } + } CODEC_LOGV("Channels: %d, SampleRate: %d, BitRate: %d, blockAlign: %d", numChannels, sampleRate, bitRate, blockAlign); @@ -5854,7 +5878,7 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { CHECK_EQ(err, (status_t)OK); CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); - CHECK_EQ(params.nBitPerSample, 16u); + //CHECK_EQ(params.nBitPerSample, 16u); CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); int32_t numChannels, sampleRate; From e31c44f9c086529c38e131f6785fbd4d3f5b900b Mon Sep 17 00:00:00 2001 From: Arne Coucheron Date: Sat, 25 Oct 2014 06:34:08 +0200 Subject: [PATCH 23/23] av: Various fixes and cleanups Change-Id: I82225d8cd3e2b3015e6c0e1dd9ddc5ec8abab525 --- media/libmedia/AudioRecord.cpp | 6 +++++- media/libmedia/AudioTrack.cpp | 2 ++ services/audioflinger/AudioFlinger.cpp | 4 ++-- services/audioflinger/AudioPolicyService.cpp | 3 ++- services/audioflinger/Threads.cpp | 6 ++++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index ee40689d2e3..c1ec876412a 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -203,17 +203,21 @@ status_t AudioRecord::set( ALOGE("Invalid format %d", format); return BAD_VALUE; } -#ifdef QCOM_HARDWARE +#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) if (format != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(format) && !audio_is_compress_capture_format(format)) { #else +#ifndef QCOM_DIRECTTRACK // Temporary restriction: AudioFlinger currently supports 16-bit PCM only if (format != AUDIO_FORMAT_PCM_16_BIT) { #endif +#endif +#ifndef QCOM_DIRECTTRACK ALOGE("Format %d is not supported", format); return BAD_VALUE; } +#endif mFormat = format; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index c94f8724c23..8b97020eae0 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -410,6 +410,7 @@ status_t AudioTrack::set( } #endif +#ifndef QCOM_DIRECTTRACK if (audio_is_linear_pcm(format)) { mFrameSize = channelCount * audio_bytes_per_sample(format); mFrameSizeAF = channelCount * sizeof(int16_t); @@ -417,6 +418,7 @@ status_t AudioTrack::set( mFrameSize = sizeof(uint8_t); mFrameSizeAF = sizeof(uint8_t); } +#endif audio_io_handle_t output = AudioSystem::getOutput( streamType, diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 1e7a8818b70..b8d8aab33f4 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1590,11 +1590,11 @@ sp AudioFlinger::openRecord( goto Exit; } #else -#if defined(QCOM_HARDWARE) +#ifdef QCOM_HARDWARE if (format != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(format) && !audio_is_compress_capture_format(format)) { -#else +#else if (format != AUDIO_FORMAT_PCM_16_BIT) { #endif ALOGE("openRecord() invalid format %d", format); diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 32efa0affcc..a23d031284d 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -540,8 +540,9 @@ bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint } Mutex::Autolock _l(mLock); return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs); -#endif +#else return 0; +#endif } bool AudioPolicyService::isSourceActive(audio_source_t source) const diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index c92eeb257c3..f93bd1dada1 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -3853,7 +3853,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun; // it will then automatically call start() when data is available -#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) +#ifdef QCOM_HARDWARE android_atomic_or(CBLK_DISABLED, &cblk->mFlags); #endif } else if (last) { @@ -5680,16 +5680,18 @@ void AudioFlinger::RecordThread::readInputParameters() mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common); mChannelCount = (uint16_t)getInputChannelCount(mChannelMask); mFormat = mInput->stream->common.get_format(&mInput->stream->common); -#ifdef QCOM_HARDWARE +#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) if (mFormat != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(mFormat) && !audio_is_compress_capture_format(mFormat)) { ALOGE("HAL format %d not supported", mFormat); } #else +#ifndef QCOM_DIRECTTRACK if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { ALOGE("HAL format %d not supported; must be AUDIO_FORMAT_PCM_16_BIT", mFormat); } +#endif #endif mFrameSize = audio_stream_frame_size(&mInput->stream->common); mBufferSize = mInput->stream->common.get_buffer_size(&mInput->stream->common);