From 2776184ae3fc6fb7541bc68cb5fe546e9824bcff Mon Sep 17 00:00:00 2001 From: Karthik Reddy Katta Date: Tue, 3 Nov 2015 16:14:27 +0530 Subject: [PATCH 01/32] libmedia: Add support for LHR tones Add tones to the ToneGenerator that are to be used for Local Hold Recall. Change-Id: I92cc1d63a3f6d38fc224774909b5b27d58be969c --- include/media/ToneGenerator.h | 2 ++ media/libmedia/ToneGenerator.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h index 8406ed64f75..0043bdcff7e 100644 --- a/include/media/ToneGenerator.h +++ b/include/media/ToneGenerator.h @@ -148,6 +148,8 @@ class ToneGenerator { TONE_CDMA_ABBR_ALERT, TONE_CDMA_SIGNAL_OFF, //CDMA end + TONE_HOLD_RECALL, + NUM_TONES, NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index 53b229ec6fe..b708e90059e 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -698,7 +698,11 @@ const ToneGenerator::ToneDescriptor ToneGenerator::sToneDescriptors[] = { { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, .repeatCnt = 0, .repeatSegment = 0 }, // TONE_CDMA_SIGNAL_OFF - + { .segments = { { .duration = 15000, .waveFreq = { 0 }, 0, 0 }, + { .duration = 500, .waveFreq = { 450, 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_HOLD_RECALL { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 350, 440, 0 }, 0, 0 }, { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, .repeatCnt = ToneGenerator::TONEGEN_INF, From 2e6d5406199d03b7eb37b5212d3e3a0f46866a41 Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Wed, 9 Dec 2015 01:16:19 +0530 Subject: [PATCH 02/32] audio : fix for 24 bit playback Fix for 24 bit playback Change-Id: I890b7805eabb3b6ae74c2f5fed55d2ef270ccfff --- media/libavextensions/mediaplayerservice/AVNuExtensions.h | 1 + media/libavextensions/mediaplayerservice/AVNuUtils.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/media/libavextensions/mediaplayerservice/AVNuExtensions.h b/media/libavextensions/mediaplayerservice/AVNuExtensions.h index d7e29d1a51f..3fc77de0441 100644 --- a/media/libavextensions/mediaplayerservice/AVNuExtensions.h +++ b/media/libavextensions/mediaplayerservice/AVNuExtensions.h @@ -85,6 +85,7 @@ struct AVNuUtils { virtual void printFileName(int fd); virtual void checkFormatChange(bool *formatChange, const sp &accessUnit); + virtual void overWriteAudioOutputFormat(sp &dst, const sp &src); virtual void addFlagsInMeta(const sp &buffer, int32_t flags, bool isAudio); virtual bool dropCorruptFrame(); diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp index 6f1fa4df328..68b6ad3e5c3 100644 --- a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp @@ -104,6 +104,9 @@ void AVNuUtils::checkFormatChange(bool * /*formatChange*/, const sp & /*accessUnit*/) { } +void AVNuUtils::overWriteAudioOutputFormat( + sp & /*dst*/, const sp & /*src*/) { +} void AVNuUtils::addFlagsInMeta(const sp & /*buffer*/, int32_t /*flags*/, bool /*isAudio*/) { } From d20af28f8f0ac851b3df7d618bcad2c7a5ce2b2b Mon Sep 17 00:00:00 2001 From: jinamdar Date: Wed, 9 Dec 2015 12:38:43 -0800 Subject: [PATCH 03/32] Combine 'DTS Sound (TruMedia) Postpro support in frameworks/av for Android 6.0' as a single patch. Signed-off-by: jinamdar (cherry picked from commit d3668da66643d4cc39058fb65c8db0742748f70f) Conflicts: services/audioflinger/AudioFlinger.cpp services/audioflinger/Threads.cpp Change-Id: I67e3ba100ff40058919ba827b806aea7bdbaf4bb --- services/audioflinger/Android.mk | 25 +++++++++++++ services/audioflinger/AudioFlinger.cpp | 24 ++++++++++++ services/audioflinger/Threads.cpp | 52 +++++++++++++++++++++++++- services/audioflinger/Threads.h | 20 +++++++++- 4 files changed, 118 insertions(+), 3 deletions(-) diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 3ea586e6474..8ea26d35ef0 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -1,3 +1,23 @@ +# +# This file was modified by DTS, Inc. The portions of the +# code that are surrounded by "DTS..." are copyrighted and +# licensed separately, as follows: +# +# (C) 2015 DTS, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) @@ -86,6 +106,11 @@ LOCAL_SRC_FILES += \ LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"' LOCAL_CFLAGS += -fvisibility=hidden +ifeq ($(strip $(BOARD_USES_SRS_TRUEMEDIA)),true) +LOCAL_SHARED_LIBRARIES += libsrsprocessing +LOCAL_CFLAGS += -DSRS_PROCESSING +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-effects +endif include $(BUILD_SHARED_LIBRARY) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index b3ba57cc248..59a0a460678 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -19,6 +19,11 @@ ** licensed separately, as follows: ** ** (C) 2011-2015 Dolby Laboratories, Inc. +** This file was modified by DTS, Inc. The portions of the +** code that are surrounded by "DTS..." are copyrighted and +** licensed separately, as follows: +** +** (C) 2015 DTS, Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -83,6 +88,9 @@ #include #include #include +#ifdef SRS_PROCESSING +#include "postpro_patch.h" +#endif // ---------------------------------------------------------------------------- @@ -1079,6 +1087,13 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& if (ioHandle == AUDIO_IO_HANDLE_NONE) { Mutex::Autolock _l(mLock); status_t final_result = NO_ERROR; +#ifdef SRS_PROCESSING + POSTPRO_PATCH_PARAMS_SET(keyValuePairs); + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + PlaybackThread *thread = mPlaybackThreads.valueAt(i).get(); + thread->setPostPro(); + } +#endif { AutoMutex lock(mHardwareLock); mHardwareStatus = AUDIO_HW_SET_PARAMETER; @@ -1173,6 +1188,9 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k if (ioHandle == AUDIO_IO_HANDLE_NONE) { String8 out_s8; +#ifdef SRS_PROCESSING + POSTPRO_PATCH_PARAMS_GET(keys, out_s8); +#endif for (size_t i = 0; i < mAudioHwDevs.size(); i++) { char *s; @@ -1398,6 +1416,12 @@ sp AudioFlinger::getEffectThread_l(int sessionId, +void AudioFlinger::PlaybackThread::setPostPro() +{ + Mutex::Autolock _l(mLock); + if (mType == OFFLOAD) + broadcast_l(); +} // ---------------------------------------------------------------------------- AudioFlinger::Client::Client(const sp& audioFlinger, pid_t pid) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 7ab15417c1c..502391877ab 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -19,6 +19,11 @@ ** licensed separately, as follows: ** ** (C) 2011-2015 Dolby Laboratories, Inc. +** This file was modified by DTS, Inc. The portions of the +** code that are surrounded by "DTS..." are copyrighted and +** licensed separately, as follows: +** +** (C) 2015 DTS, Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -91,6 +96,9 @@ #include #endif +#ifdef SRS_PROCESSING +#include "postpro_patch.h" +#endif // ---------------------------------------------------------------------------- // Note: the following macro is used for extremely verbose logging message. In @@ -2759,6 +2767,19 @@ bool AudioFlinger::PlaybackThread::threadLoop() const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid())); acquireWakeLock(); +#ifdef SRS_PROCESSING + String8 bt_param = String8("bluetooth_enabled=0"); + POSTPRO_PATCH_PARAMS_SET(bt_param); + if (mType == MIXER) { + POSTPRO_PATCH_OUTPROC_PLAY_INIT(this, myName); + } else if (mType == OFFLOAD) { + POSTPRO_PATCH_OUTPROC_DIRECT_INIT(this, myName); + POSTPRO_PATCH_OUTPROC_PLAY_ROUTE_BY_VALUE(this, mOutDevice); + } else if (mType == DIRECT) { + POSTPRO_PATCH_OUTPROC_DIRECT_INIT(this, myName); + POSTPRO_PATCH_OUTPROC_PLAY_ROUTE_BY_VALUE(this, mOutDevice); + } +#endif // mNBLogWriter->log can only be called while thread mutex mLock is held. // So if you need to log when mutex is unlocked, set logString to a non-NULL string, @@ -2957,7 +2978,13 @@ bool AudioFlinger::PlaybackThread::threadLoop() effectChains[i]->process_l(); } } - +#ifdef SRS_PROCESSING + // Offload thread + if (mType == OFFLOAD) { + char buffer[2]; + POSTPRO_PATCH_OUTPROC_DIRECT_SAMPLES(this, AUDIO_FORMAT_PCM_16_BIT, (int16_t *) buffer, 2, 48000, 2); + } +#endif // Only if the Effects buffer is enabled and there is data in the // Effects buffer (buffer valid), we need to // copy into the sink buffer. @@ -2975,6 +3002,11 @@ bool AudioFlinger::PlaybackThread::threadLoop() // mSleepTimeUs == 0 means we must write to audio hardware if (mSleepTimeUs == 0) { ssize_t ret = 0; +#ifdef SRS_PROCESSING + if (mType == MIXER && mMixerStatus == MIXER_TRACKS_READY) { + POSTPRO_PATCH_OUTPROC_PLAY_SAMPLES(this, mFormat, mSinkBuffer, mSinkBufferSize, mSampleRate, mChannelCount); + } +#endif if (mBytesRemaining) { ret = threadLoop_write(); if (ret < 0) { @@ -3070,7 +3102,15 @@ bool AudioFlinger::PlaybackThread::threadLoop() threadLoop_standby(); mStandby = true; } - +#ifdef SRS_PROCESSING + if (mType == MIXER) { + POSTPRO_PATCH_OUTPROC_PLAY_EXIT(this, myName); + } else if (mType == OFFLOAD) { + POSTPRO_PATCH_OUTPROC_DIRECT_EXIT(this, myName); + } else if (mType == DIRECT) { + POSTPRO_PATCH_OUTPROC_DIRECT_EXIT(this, myName); + } +#endif releaseWakeLock(); mWakeLockUids.clear(); mActiveTracksGeneration++; @@ -3164,6 +3204,10 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat type |= patch->sinks[i].ext.device.type; } +#ifdef SRS_PROCESSING + POSTPRO_PATCH_OUTPROC_PLAY_ROUTE_BY_VALUE(this, type); +#endif + #ifdef ADD_BATTERY_DATA // when changing the audio output device, call addBatteryData to notify // the change @@ -4342,6 +4386,9 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa AudioParameter param = AudioParameter(keyValuePair); int value; +#ifdef SRS_PROCESSING + POSTPRO_PATCH_OUTPROC_PLAY_ROUTE(this, param, value); +#endif if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { reconfig = true; } @@ -4886,6 +4933,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key AudioParameter param = AudioParameter(keyValuePair); int value; + if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { // forward device change to effects that have requested to be // aware of attached audio device. diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 9e32ea1a1f3..23cc68bf466 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -13,6 +13,24 @@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. +** +** This file was modified by DTS, Inc. The portions of the +** code that are surrounded by "DTS..." are copyrighted and +** licensed separately, as follows: +** +** (C) 2015 DTS, Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. */ #ifndef INCLUDING_FROM_AUDIOFLINGER_H @@ -537,7 +555,7 @@ class PlaybackThread : public ThreadBase { void setMasterVolume(float value); void setMasterMute(bool muted); - + void setPostPro(); void setStreamVolume(audio_stream_type_t stream, float value); void setStreamMute(audio_stream_type_t stream, bool muted); From c3d1f2c7a3eed2567d1b186f896c417523c4f7ef Mon Sep 17 00:00:00 2001 From: Amal Paul Date: Sun, 6 Dec 2015 15:21:52 -0800 Subject: [PATCH 04/32] frameworks/av: Integrate DTS M6/M8 decoder Signed-off-by: Amal Paul (cherry picked from commit badb363eb16ceb9ffe880c486585ac8027597677) Conflicts: media/libstagefright/ACodec.cpp media/libstagefright/MPEG4Extractor.cpp media/libstagefright/OMXCodec.cpp media/libstagefright/omx/SoftOMXPlugin.cpp Change-Id: I82423b1947e0b174bcb2fc69561b75fae3ae3917 --- media/libstagefright/ACodec.cpp | 63 +++++ media/libstagefright/Android.mk | 24 ++ media/libstagefright/DTSUtils.cpp | 100 ++++++++ media/libstagefright/MPEG4Extractor.cpp | 38 +++ media/libstagefright/OMXCodec.cpp | 41 +++ media/libstagefright/codecs/dtsdec/Android.mk | 28 +++ media/libstagefright/codecs/dtsdec/NOTICE | 188 ++++++++++++++ .../codecs/dtsdec/SoftDTSDec.cpp | 177 +++++++++++++ .../libstagefright/codecs/dtsdec/SoftDTSDec.h | 72 ++++++ media/libstagefright/include/DTSUtils.h | 40 +++ media/libstagefright/include/OMX_Audio_DTS.h | 238 ++++++++++++++++++ media/libstagefright/omx/Android.mk | 4 + media/libstagefright/omx/SoftOMXPlugin.cpp | 21 ++ 13 files changed, 1034 insertions(+) create mode 100644 media/libstagefright/DTSUtils.cpp create mode 100644 media/libstagefright/codecs/dtsdec/Android.mk create mode 100644 media/libstagefright/codecs/dtsdec/NOTICE create mode 100644 media/libstagefright/codecs/dtsdec/SoftDTSDec.cpp create mode 100644 media/libstagefright/codecs/dtsdec/SoftDTSDec.h create mode 100644 media/libstagefright/include/DTSUtils.h create mode 100644 media/libstagefright/include/OMX_Audio_DTS.h diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 677e2d7a266..c0b966eef14 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -31,6 +31,24 @@ * See the License for the specific language governing permissions and * limitations under the License. * + ** + ** This file was modified by DTS, Inc. The portions of the + ** code that are surrounded by "DTS..." are copyrighted and + ** licensed separately, as follows: + ** + ** (C) 2015 DTS, Inc. + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License */ //#define LOG_NDEBUG 0 @@ -78,6 +96,11 @@ #include "DolbyACodecExtImpl.h" #endif // DOLBY_END +#ifdef DTS_CODEC_M_ +#include "include/DTSUtils.h" +#include "include/OMX_Audio_DTS.h" +#endif + namespace android { // OMX errors are directly mapped into status_t range if @@ -1602,6 +1625,10 @@ status_t ACodec::setComponentRole( { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, "audio_decoder.eac3_joc", NULL }, #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + { MEDIA_MIMETYPE_AUDIO_DTS, + "audio_decoder.dts", "audio_encoder.dts" }, +#endif }; static const size_t kNumMimeToRole = @@ -2026,6 +2053,25 @@ status_t ACodec::configureCodec( sampleRate, numChannels); } +#ifdef DTS_CODEC_M_ + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_DTS)) { + ALOGV(" (DTS) mime == MEDIA_MIMETYPE_AUDIO_DTS"); + int32_t numChannels, sampleRate; + int32_t bitWidth = 24; + if (!msg->findInt32("channel-count", &numChannels) + || !msg->findInt32("sample-rate", &sampleRate)) { + ALOGE(" (DTS) missing channel count or sample rate for DTS decoder"); + err = INVALID_OPERATION; + } else { + ALOGI(" (DTS) bit width to setup decoder %d", bitWidth); + err = DTSUtils::setupDecoder(mOMX, mNode, sampleRate, bitWidth); + // Also update output format bit-width so ACodec client too gets to know + outputFormat->setInt32("bit-width", bitWidth); + } + if (err != OK) { + return err; + } +#endif } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { int32_t numChannels, sampleRate; if (!msg->findInt32("channel-count", &numChannels) @@ -4443,6 +4489,23 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { notify->setInt32("sample-rate", params.nSamplingRate); break; } +#ifdef DTS_CODEC_M_ + case OMX_AUDIO_CodingDTSHD: + { + OMX_AUDIO_PARAM_DTSDECTYPE params; + InitOMXParams(¶ms); + params.nPortIndex = portIndex; + + CHECK_EQ((status_t)OK, mOMX->getParameter( + mNode, + (OMX_INDEXTYPE)OMX_IndexParamAudioDTSDec, + ¶ms, + sizeof(params))); + + notify->setString("mime", MEDIA_MIMETYPE_AUDIO_DTS); + break; + } +#endif default: ALOGE("Unsupported audio coding: %s(%d)\n", diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 9687c7d3c78..686af155b1b 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -1,3 +1,22 @@ +# +# This file was modified by DTS, Inc. The portions of the +# code that are surrounded by "DTS..." are copyrighted and +# licensed separately, as follows: +# +# (C) 2015 DTS, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +# LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) @@ -150,6 +169,11 @@ endif LOCAL_CLANG := true +ifeq ($(DTS_CODEC_M_), true) + LOCAL_SRC_FILES+= DTSUtils.cpp + LOCAL_CFLAGS += -DDTS_CODEC_M_ +endif + LOCAL_MODULE:= libstagefright LOCAL_MODULE_TAGS := optional diff --git a/media/libstagefright/DTSUtils.cpp b/media/libstagefright/DTSUtils.cpp new file mode 100644 index 00000000000..9dea4bdc566 --- /dev/null +++ b/media/libstagefright/DTSUtils.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NDEBUG 0 +#define LOG_TAG "DTSUtils" +#include + +#include "include/DTSUtils.h" + +#include +#include "include/OMX_Audio_DTS.h" + +namespace android { + +status_t DTSUtils::setupDecoder(sp omx, IOMX::node_id node, int32_t sampleRate, int32_t bitWidth) +{ + ALOGV("(DTS) +setupDecoder()"); + + status_t result; + OMX_AUDIO_PARAM_DTSDECTYPE myDtsDecParam; + + // initialize myDtsDecParam + memset(&myDtsDecParam, 0, sizeof(myDtsDecParam)); + InitOMXParams(&myDtsDecParam); + + // get the current params + result = omx->getParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioDTSDec, &myDtsDecParam, sizeof(myDtsDecParam)); + ALOGV("(DTS) -> omx->getParameter() : node = %d nSpkrOut = %d result = 0x%x", (int)node, (int)myDtsDecParam.nSpkrOut, (int)result); + + if (result == OK) + { + myDtsDecParam.nOutputBitWidth = bitWidth; + ALOGV("(DTS) nOutputBitWidth = %d", myDtsDecParam.nOutputBitWidth); + // Set 7.1 channel speaker mask for M8: 0x84B (2123) == C-LR-LFE1-LssRss-LsrRsr + // M6 will internally set speaker mask to 0xF (15) == C-LR-LsRs-LFE1 + myDtsDecParam.nSpkrOut = OMX_AUDIO_DTS_SPKROUTTYPE( OMX_AUDIO_DTSSPKROUT_MASK_C + | OMX_AUDIO_DTSSPKROUT_MASK_LR + | OMX_AUDIO_DTSSPKROUT_MASK_LFE1 + | OMX_AUDIO_DTSSPKROUT_MASK_LssRss + | OMX_AUDIO_DTSSPKROUT_MASK_LsrRsr + ); + // call Android's OMX setParameter wrapper + ALOGV("(DTS) -> Attempting to set multichannel speaker mask : nSpkrOut = 0x%x (%d)", (int)myDtsDecParam.nSpkrOut, (int)myDtsDecParam.nSpkrOut); + result = omx->setParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioDTSDec, &myDtsDecParam, sizeof(myDtsDecParam)); + ALOGV("(DTS) -> omx->setParameter() : node = %d result = 0x%x", (int)node, (int)result); + + if (result == OK) + { + // make sure the param got set + result = omx->getParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioDTSDec, &myDtsDecParam, sizeof(myDtsDecParam)); + ALOGV("(DTS) -> node->getParameter() : node = %d nSpkrOut = 0x%x (%d) result = 0x%x", (int)node, (int)myDtsDecParam.nSpkrOut, (int)myDtsDecParam.nSpkrOut, (int)result); + } + } + + ALOGV("(DTS) -setupDecoder() : nSpkrOut result = 0x%x", (int)result); + + // initialize myPcmParam + OMX_AUDIO_PARAM_PCMMODETYPE myPcmParam; + memset(&myPcmParam, 0, sizeof(myPcmParam)); + InitOMXParams(&myPcmParam); + myPcmParam.nPortIndex = 1; + + result = omx->getParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &myPcmParam, sizeof(myPcmParam)); + ALOGV("(DTS) -> omx->getParameter() : node = %d nSamplingRate = %d result = 0x%x", (int)node, (int)myPcmParam.nSamplingRate, (int)result); + + if (result == OK) + { + myPcmParam.nSamplingRate = sampleRate; + // call Android's OMX setParameter wrapper + ALOGV("(DTS) -> Attempting to set sampling rate : nSamplingRate = 0x%x (%d)", (int)myPcmParam.nSamplingRate, (int)myPcmParam.nSamplingRate); + result = omx->setParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &myPcmParam, sizeof(myPcmParam)); + ALOGV("(DTS) -> omx->setParameter() : node = %d result = 0x%x", (int)node, (int)result); + + if (result == OK) + { + // make sure the param got set + result = omx->getParameter(node, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &myPcmParam, sizeof(myPcmParam)); + ALOGV("(DTS) -> node->getParameter() : node = %d nSamplingRate = 0x%x (%d) result = 0x%x", (int)node, (int)myPcmParam.nSamplingRate, (int)myPcmParam.nSamplingRate, (int)result); + } + } + + ALOGV("(DTS) -setupDecoder() : nSamplingRate result = 0x%x", (int)result); + + return result; +} + +} // namespace android diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index e46bc885ca5..6db2dc0e5bb 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -31,6 +31,24 @@ * See the License for the specific language governing permissions and * limitations under the License. * + ** + ** This file was modified by DTS, Inc. The portions of the + ** code that are surrounded by "DTS..." are copyrighted and + ** licensed separately, as follows: + ** + ** (C) 2015 DTS, Inc. + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License */ //#define LOG_NDEBUG 0 @@ -351,6 +369,20 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('s', 'a', 'w', 'b'): return MEDIA_MIMETYPE_AUDIO_AMR_WB; +#ifdef DTS_CODEC_M_ + case FOURCC('d', 't', 's', 'c'): + return MEDIA_MIMETYPE_AUDIO_DTS; + + case FOURCC('d', 't', 's', 'h'): + return MEDIA_MIMETYPE_AUDIO_DTS; + + case FOURCC('d', 't', 's', 'l'): + return MEDIA_MIMETYPE_AUDIO_DTS; + + case FOURCC('d', 't', 's', 'e'): + return MEDIA_MIMETYPE_AUDIO_DTS; +#endif + case FOURCC('m', 'p', '4', 'v'): return MEDIA_MIMETYPE_VIDEO_MPEG4; @@ -1368,6 +1400,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('a', 'c', '-', '3'): case FOURCC('e', 'c', '-', '3'): #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + case FOURCC('d', 't', 's', 'c'): + case FOURCC('d', 't', 's', 'h'): + case FOURCC('d', 't', 's', 'l'): + case FOURCC('d', 't', 's', 'e'): +#endif { uint8_t buffer[8 + 20]; if (chunk_data_size < (ssize_t)sizeof(buffer)) { diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 47622172a97..e657ebc5ea3 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -31,6 +31,24 @@ * See the License for the specific language governing permissions and * limitations under the License. * + ** + ** This file was modified by DTS, Inc. The portions of the + ** code that are surrounded by "DTS..." are copyrighted and + ** licensed separately, as follows: + ** + ** (C) 2015 DTS, Inc. + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License */ #include @@ -78,6 +96,11 @@ #include "DolbyOMXCodecExtImpl.h" #endif // DOLBY_END +#ifdef DTS_CODEC_M_ +#include "include/DTSUtils.h" +#include "include/OMX_Audio_DTS.h" +#endif + namespace android { // Treat time out as an error if we have not received any output @@ -679,6 +702,20 @@ status_t OMXCodec::configureCodec(const sp &meta) { CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); +#ifdef DTS_CODEC_M_ + } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_DTS, mMIME)) { + ALOGV(" (DTS) mime == MEDIA_MIMETYPE_AUDIO_DTS"); + int32_t numChannels, sampleRate; + int32_t bitWidth = 24; + CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); + CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); + + status_t err = DTSUtils::setupDecoder(mOMX, mNode, sampleRate, bitWidth); + + if (err != OK) { + return err; + } +#endif } if (!strncasecmp(mMIME, "video/", 6)) { @@ -1546,6 +1583,10 @@ void OMXCodec::setComponentRole( { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, "audio_decoder.eac3_joc", NULL }, #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + { MEDIA_MIMETYPE_AUDIO_DTS, + "audio_decoder.dts", "audio_encoder.dts" }, +#endif }; static const size_t kNumMimeToRole = diff --git a/media/libstagefright/codecs/dtsdec/Android.mk b/media/libstagefright/codecs/dtsdec/Android.mk new file mode 100644 index 00000000000..033134fa501 --- /dev/null +++ b/media/libstagefright/codecs/dtsdec/Android.mk @@ -0,0 +1,28 @@ +LOCAL_PATH:= $(call my-dir) + +ifeq ($(DTS_CODEC_M_), true) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SoftDTSDec.cpp + +LOCAL_C_INCLUDES := \ + frameworks/av/media/libstagefright/include \ + frameworks/native/include/media/openmax + +LOCAL_CFLAGS := + +LOCAL_CFLAGS += -Werror + +LOCAL_SHARED_LIBRARIES := \ + libomx-dts \ + libstagefright_omx libstagefright_foundation libutils libcutils libdl + +LOCAL_MODULE := libstagefright_soft_dtsdec +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/media/libstagefright/codecs/dtsdec/NOTICE b/media/libstagefright/codecs/dtsdec/NOTICE new file mode 100644 index 00000000000..43a77c62ac0 --- /dev/null +++ b/media/libstagefright/codecs/dtsdec/NOTICE @@ -0,0 +1,188 @@ + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/media/libstagefright/codecs/dtsdec/SoftDTSDec.cpp b/media/libstagefright/codecs/dtsdec/SoftDTSDec.cpp new file mode 100644 index 00000000000..3cc7a521cab --- /dev/null +++ b/media/libstagefright/codecs/dtsdec/SoftDTSDec.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SoftDTSDec" +#define LOG_NDEBUG 0 +#include +#include + +#include "SoftDTSDec.h" + +#include +#include +#include +#include + +#include "OMX_Core.h" +#include "OMX_Audio_DTS.h" + +#define DTS_ALOGV +//#define DTS_ALOGV ALOGV + +namespace android { + +template +static void InitOMXParams(T *params) { + params->nSize = sizeof(T); + params->nVersion.s.nVersionMajor = 1; + params->nVersion.s.nVersionMinor = 0; + params->nVersion.s.nRevision = 0; + params->nVersion.s.nStep = 0; +} + + +SoftDTSDec::SoftDTSDec( const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component ) + : SimpleSoftOMXComponent(name, callbacks, appData, component), + mComponentHandle(NULL) +{ + DTS_ALOGV("+SoftDTSDec() ctor : name = '%s' this = 0x%x", name, this); + + OMX_Init(); + + OMX_ERRORTYPE retVal = OMX_GetHandle( &mComponentHandle, + const_cast(name), + appData, + const_cast(callbacks) ); +} + + +SoftDTSDec::~SoftDTSDec() +{ + DTS_ALOGV("+ ~SoftDTSDec() (dtor)"); + + OMX_FreeHandle(mComponentHandle); + OMX_Deinit(); + + DTS_ALOGV("- ~SoftDTSDec() (dtor)"); +} + + +OMX_ERRORTYPE SoftDTSDec::sendCommand(OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) +{ + OMX_ERRORTYPE retVal = OMX_SendCommand(mComponentHandle, cmd, param, data); + DTS_ALOGV("sendCommand() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::getParameter(OMX_INDEXTYPE index, OMX_PTR params) +{ + OMX_ERRORTYPE retVal = OMX_GetParameter(mComponentHandle, index, params); + DTS_ALOGV("getParameter() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::setParameter(OMX_INDEXTYPE index, const OMX_PTR params) +{ + OMX_ERRORTYPE retVal = OMX_SetParameter(mComponentHandle, index, params); + DTS_ALOGV("setParameter() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::getConfig(OMX_INDEXTYPE index, OMX_PTR params) +{ + OMX_ERRORTYPE retVal = OMX_GetConfig(mComponentHandle, index, params); + DTS_ALOGV("getConfig() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::setConfig(OMX_INDEXTYPE index, const OMX_PTR params) +{ + OMX_ERRORTYPE retVal = OMX_SetConfig(mComponentHandle, index, params); + DTS_ALOGV("setConfig() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::getExtensionIndex(const char *name, OMX_INDEXTYPE *index) +{ + OMX_ERRORTYPE retVal = OMX_GetExtensionIndex(mComponentHandle, (OMX_STRING)name, index); + DTS_ALOGV("getExtensionIndex() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::useBuffer(OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size, + OMX_U8 *ptr) +{ + OMX_ERRORTYPE retVal = OMX_UseBuffer(mComponentHandle, buffer, portIndex, appPrivate, size, ptr); + DTS_ALOGV("useBuffer() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::allocateBuffer(OMX_BUFFERHEADERTYPE **header, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size) +{ + OMX_ERRORTYPE retVal = OMX_AllocateBuffer(mComponentHandle, header, portIndex, appPrivate, size); + DTS_ALOGV("allocateBuffer() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::freeBuffer(OMX_U32 portIndex, OMX_BUFFERHEADERTYPE *header) +{ + OMX_ERRORTYPE retVal = OMX_FreeBuffer(mComponentHandle, portIndex, header); + DTS_ALOGV("freeBuffer() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::emptyThisBuffer(OMX_BUFFERHEADERTYPE *buffer) +{ + OMX_ERRORTYPE retVal = OMX_EmptyThisBuffer(mComponentHandle, buffer); + DTS_ALOGV("emptyThisBuffer() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::fillThisBuffer(OMX_BUFFERHEADERTYPE *buffer) +{ + OMX_ERRORTYPE retVal = OMX_FillThisBuffer(mComponentHandle, buffer); + DTS_ALOGV("fillThisBuffer() returns 0x%x", retVal); + return retVal; +} + +OMX_ERRORTYPE SoftDTSDec::getState(OMX_STATETYPE *state) +{ + OMX_ERRORTYPE retVal = OMX_GetState(mComponentHandle, state); + DTS_ALOGV("getState() returns 0x%x", retVal); + return retVal; +} + +} // namespace android + +android::SoftOMXComponent *createSoftOMXComponent( + const char *name, const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, OMX_COMPONENTTYPE **component) { + ALOGV("createSoftOMXComponent called for SoftDTSDec"); + + android::SoftDTSDec * dtsDec = new android::SoftDTSDec(name, callbacks, appData, component); + + return dtsDec; +} diff --git a/media/libstagefright/codecs/dtsdec/SoftDTSDec.h b/media/libstagefright/codecs/dtsdec/SoftDTSDec.h new file mode 100644 index 00000000000..83ac58db480 --- /dev/null +++ b/media/libstagefright/codecs/dtsdec/SoftDTSDec.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFT_DTS_DEC_H_ +#define SOFT_DTS_DEC_H_ + +#include "SimpleSoftOMXComponent.h" + +namespace android { + +struct SoftDTSDec : public SimpleSoftOMXComponent +{ + SoftDTSDec( const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component ); + + OMX_ERRORTYPE sendCommand(OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data); + + OMX_ERRORTYPE getParameter(OMX_INDEXTYPE index, OMX_PTR params); + OMX_ERRORTYPE setParameter(OMX_INDEXTYPE index, const OMX_PTR params); + + OMX_ERRORTYPE getConfig(OMX_INDEXTYPE index, OMX_PTR params); + OMX_ERRORTYPE setConfig(OMX_INDEXTYPE index, const OMX_PTR params); + + OMX_ERRORTYPE getExtensionIndex(const char *name, OMX_INDEXTYPE *index); + + OMX_ERRORTYPE useBuffer(OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size, + OMX_U8 *ptr); + + OMX_ERRORTYPE allocateBuffer(OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size); + + OMX_ERRORTYPE freeBuffer(OMX_U32 portIndex, + OMX_BUFFERHEADERTYPE *buffer); + + OMX_ERRORTYPE emptyThisBuffer(OMX_BUFFERHEADERTYPE *buffer); + + OMX_ERRORTYPE fillThisBuffer(OMX_BUFFERHEADERTYPE *buffer); + + OMX_ERRORTYPE getState(OMX_STATETYPE *state); + +protected: + ~SoftDTSDec(); + +private: + OMX_HANDLETYPE mComponentHandle; // handle to DTS OMX component instance + + DISALLOW_EVIL_CONSTRUCTORS(SoftDTSDec); +}; + +} // namespace android + +#endif // SOFT_DTS_DEC_H_ diff --git a/media/libstagefright/include/DTSUtils.h b/media/libstagefright/include/DTSUtils.h new file mode 100644 index 00000000000..832fc0eac8d --- /dev/null +++ b/media/libstagefright/include/DTSUtils.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _DTSUtils_h +#define _DTSUtils_h + +#include + +namespace android { + +struct DTSUtils +{ + template + static void InitOMXParams(T *params) { + params->nSize = sizeof(T); + params->nVersion.s.nVersionMajor = 1; + params->nVersion.s.nVersionMinor = 0; + params->nVersion.s.nRevision = 0; + params->nVersion.s.nStep = 0; + } + + static status_t setupDecoder(sp omx, IOMX::node_id node, int32_t sampleRate, int32_t bitWidth); +}; + +} // namespace android + +#endif diff --git a/media/libstagefright/include/OMX_Audio_DTS.h b/media/libstagefright/include/OMX_Audio_DTS.h new file mode 100644 index 00000000000..c3b6750c290 --- /dev/null +++ b/media/libstagefright/include/OMX_Audio_DTS.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/*======================================================================* + + DTS, Inc. + 5220 Las Virgenes Road + Calabasas, CA 91302 USA + + CONFIDENTIAL: CONTAINS CONFIDENTIAL PROPRIETARY INFORMATION OWNED BY + DTS, INC. AND/OR ITS AFFILIATES (�DTS�), INCLUDING BUT NOT LIMITED TO + TRADE SECRETS, KNOW-HOW, TECHNICAL AND BUSINESS INFORMATION. USE, + DISCLOSURE OR DISTRIBUTION OF THE SOFTWARE IN ANY FORM IS LIMITED TO + SPECIFICALLY AUTHORIZED LICENSEES OF DTS. ANY UNAUTHORIZED + DISCLOSURE IS A VIOLATION OF STATE, FEDERAL, AND dtsInt32ERNATIONAL LAWS. + BOTH CIVIL AND CRIMINAL PENALTIES APPLY. + + DO NOT DUPLICATE. COPYRIGHT 2010, DTS, INC. ALL RIGHTS RESERVED. + UNAUTHORIZED DUPLICATION IS A VIOLATION OF STATE, FEDERAL AND + dtsInt32ERNATIONAL LAWS. + + ALGORITHMS, DATA STRUCTURES AND METHODS CONTAINED IN THIS SOFTWARE + MAY BE PROTECTED BY ONE OR MORE PATENTS OR PATENT APPLICATIONS. + + UNLESS OTHERWISE PROVIDED UNDER THE TERMS OF A FULLY-EXECUTED WRITTEN + AGREEMENT BY AND BETWEEN THE RECIPIENT HEREOF AND DTS, THE FOLLOWING + TERMS SHALL APPLY TO ANY USE OF THE SOFTWARE (THE �PRODUCT�) AND, AS + APPLICABLE, ANY RELATED DOCUMENTATION: (i) ANY USE OF THE PRODUCT + AND ANY RELATED DOCUMENTATION IS AT THE RECIPIENT�S SOLE RISK: + (ii) THE PRODUCT AND ANY RELATED DOCUMENTATION ARE PROVIDED �AS IS� + AND WITHOUT WARRANTY OF ANY KIND AND DTS EXPRESSLY DISCLAIMS ALL + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDLESS OF WHETHER DTS KNOWS OR HAS REASON TO KNOW OF THE + USER�S PARTICULAR NEEDS; (iii) DTS DOES NOT WARRANT THAT THE PRODUCT + OR ANY RELATED DOCUMENTATION WILL MEET USER�S REQUIREMENTS, OR THAT + DEFECTS IN THE PRODUCT OR ANY RELATED DOCUMENTATION WILL BE + CORRECTED; (iv) DTS DOES NOT WARRANT THAT THE OPERATION OF ANY + HARDWARE OR SOFTWARE ASSOCIATED WITH THIS DOCUMENT WILL BE + UNdtsInt32ERRUPTED OR ERROR-FREE; AND (v) UNDER NO CIRCUMSTANCES, + INCLUDING NEGLIGENCE, SHALL DTS OR THE DIRECTORS, OFFICERS, EMPLOYEES, + OR AGENTS OF DTS, BE LIABLE TO USER FOR ANY INCIDENTAL, INDIRECT, + SPECIAL, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO + DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS dtsInt32ERRUPTION, AND LOSS + OF BUSINESS INFORMATION) ARISING OUT OF THE USE, MISUSE, OR INABILITY + TO USE THE PRODUCT OR ANY RELATED DOCUMENTATION. + + UNRELEASED SOFTWARE: + Please note that this software is "unreleased" software, which means that + it is not complete and may have known or unknown problems or malfunctions + ("bugs"). It is provided for purposes of testing in order to obtain + feedback, and is not dtsInt32ended to provide a long term solution for any + customer need. The software may not work as expected; the documentation + is incomplete; there are no tutorials or troubleshooting procedures provided. + The software may not work on all platforms or under all operating systems. + Not all hardware is supported. For these reasons, the software should never + be used for critical applications where failure would have any serious + consequence. We may undertake to fix "bugs" as they are reported, to complete + the feature set, and to produce documentation for future versions. We dtsInt32end + to release new versions (either "beta" or for release), but we cannot + guarantee to resolve any particular problem in any particular time frame. + Although we appreciate your feedback and dtsInt32end to undertake to correct "bugs" + as they are reported, we do not guarantee support for this version of + the software for any period whatsoever. +*======================================================================*/ + + +/** @file OMX_Audio_DTS.h - OpenMax IL version 1.1.2, DTS vendor extension + * The structures needed by Audio components to exchange + * parameters and configuration data with the componenmilts. + */ + +#ifndef OMX_Audio_DTS_h +#define OMX_Audio_DTS_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Extension to OMX_AUDIO_DTSCODINGTYPE */ +typedef enum +{ + OMX_AUDIO_CodingDTSHD = OMX_AUDIO_CodingVendorStartUnused + 0x1, /**< DTS-HD vendor extension */ +} OMX_AUDIO_DTS_CODINGTYPE; + + +/* Extension to OMX_AUDIO_CHANNELTYPE */ +typedef enum +{ + OMX_AUDIO_ChannelLSS = OMX_AUDIO_ChannelVendorStartUnused + 0x1,/**< Left Surround on Side */ + OMX_AUDIO_ChannelRSS, /**< Right Surround on Side */ + OMX_AUDIO_ChannelLC, /**< Between Left and Centre in front */ + OMX_AUDIO_ChannelRC, /**< Between Right and Centre in front */ + OMX_AUDIO_ChannelLH, /**< Left Height in front */ + OMX_AUDIO_ChannelCH, /**< Centre Height in Front */ + OMX_AUDIO_ChannelRH, /**< Right Height in front */ + OMX_AUDIO_ChannelLFE2, /**< Low Frequency Effects 2 */ + OMX_AUDIO_ChannelLW, /**< Left on side in front */ + OMX_AUDIO_ChannelRW, /**< Right on side in front */ + OMX_AUDIO_ChannelOH, /**< Over the listeners Head */ + OMX_AUDIO_ChannelLHS, /**< Left Height on Side */ + OMX_AUDIO_ChannelRHS, /**< Right Height on Side */ + OMX_AUDIO_ChannelCHR, /**< Centre Height in Rear */ + OMX_AUDIO_ChannelLHR, /**< Left Height in Rear */ + OMX_AUDIO_ChannelRHR, /**< Right Height in Rear */ + OMX_AUDIO_ChannelCLF, /* < Low Center in Front */ + OMX_AUDIO_ChannelLLF, /* < Low Left in Front */ + OMX_AUDIO_ChannelRLF, /* < Low Right in Front */ + OMX_AUDIO_ChannelLT, /**< Left Total */ + OMX_AUDIO_ChannelRT /**< Right Total */ +} OMX_AUDIO_DTS_CHANNELTYPE; + + +typedef enum OMX_AUDIO_DTS_SPKROUTTYPE +{ + OMX_AUDIO_DTSSPKROUT_MASK_NATIVE = 0x00000, + OMX_AUDIO_DTSSPKROUT_MASK_C = 0x00001, + OMX_AUDIO_DTSSPKROUT_MASK_LR = 0x00002, + OMX_AUDIO_DTSSPKROUT_MASK_LsRs = 0x00004, + OMX_AUDIO_DTSSPKROUT_MASK_LFE1 = 0x00008, + OMX_AUDIO_DTSSPKROUT_MASK_Cs = 0x00010, + OMX_AUDIO_DTSSPKROUT_MASK_LhRh = 0x00020, + OMX_AUDIO_DTSSPKROUT_MASK_LsrRsr = 0x00040, + OMX_AUDIO_DTSSPKROUT_MASK_Ch = 0x00080, + OMX_AUDIO_DTSSPKROUT_MASK_Oh = 0x00100, + OMX_AUDIO_DTSSPKROUT_MASK_LcRc = 0x00200, + OMX_AUDIO_DTSSPKROUT_MASK_LwRw = 0x00400, + OMX_AUDIO_DTSSPKROUT_MASK_LssRss = 0x00800, + OMX_AUDIO_DTSSPKROUT_MASK_LFE_2 = 0x01000, + OMX_AUDIO_DTSSPKROUT_MASK_LhsRhs = 0x02000, + OMX_AUDIO_DTSSPKROUT_MASK_Chr = 0x04000, + OMX_AUDIO_DTSSPKROUT_MASK_LhrRhr = 0x08000, + OMX_AUDIO_DTSSPKROUT_MASK_Clf = 0x10000, + OMX_AUDIO_DTSSPKROUT_MASK_LlfRlf = 0x20000, + OMX_AUDIO_DTSSPKROUT_MASK_LtRt = 0x40000 +} OMX_AUDIO_DTS_SPKROUTTYPE; + + +typedef enum +{ + OMX_AUDIO_DTSSPEAKERMASK_CENTRE = 0x00000001, /**< Centre */ + OMX_AUDIO_DTSSPEAKERMASK_LEFT = 0x00000002, /**< Left */ + OMX_AUDIO_DTSSPEAKERMASK_RIGHT = 0x00000004, /**< Right */ + OMX_AUDIO_DTSSPEAKERMASK_LS = 0x00000008, /**< Left Surround */ + OMX_AUDIO_DTSSPEAKERMASK_RS = 0x00000010, /**< Right Surround */ + OMX_AUDIO_DTSSPEAKERMASK_LFE1 = 0x00000020, /**< Low Frequency Effects 1 */ + OMX_AUDIO_DTSSPEAKERMASK_Cs = 0x00000040, /**< Center Surround */ + OMX_AUDIO_DTSSPEAKERMASK_Lsr = 0x00000080, /**< Left Surround in Rear */ + OMX_AUDIO_DTSSPEAKERMASK_Rsr = 0x00000100, /**< Right Surround in Rear */ + OMX_AUDIO_DTSSPEAKERMASK_Lss = 0x00000200, /**< Left Surround on Side */ + OMX_AUDIO_DTSSPEAKERMASK_Rss = 0x00000400, /**< Right Surround on Side */ + OMX_AUDIO_DTSSPEAKERMASK_Lc = 0x00000800, /**< Between Left and Centre in front */ + OMX_AUDIO_DTSSPEAKERMASK_Rc = 0x00001000, /**< Between Right and Centre in front */ + OMX_AUDIO_DTSSPEAKERMASK_Lh = 0x00002000, /**< Left Height in front */ + OMX_AUDIO_DTSSPEAKERMASK_Ch = 0x00004000, /**< Centre Height in Front */ + OMX_AUDIO_DTSSPEAKERMASK_Rh = 0x00008000, /**< Right Height in front */ + OMX_AUDIO_DTSSPEAKERMASK_LFE2 = 0x00010000, /**< Low Frequency Effects 2 */ + OMX_AUDIO_DTSSPEAKERMASK_Lw = 0x00020000, /**< Left on side in front */ + OMX_AUDIO_DTSSPEAKERMASK_Rw = 0x00040000, /**< Right on side in front */ + OMX_AUDIO_DTSSPEAKERMASK_Oh = 0x00080000, /**< Over the listeners Head */ + OMX_AUDIO_DTSSPEAKERMASK_Lhs = 0x00100000, /**< Left Height on Side */ + OMX_AUDIO_DTSSPEAKERMASK_Rhs = 0x00200000, /**< Right Height on Side */ + OMX_AUDIO_DTSSPEAKERMASK_Chr = 0x00400000, /**< Centre Height in Rear */ + OMX_AUDIO_DTSSPEAKERMASK_Lhr = 0x00800000, /**< Left Height in Rear */ + OMX_AUDIO_DTSSPEAKERMASK_Rhr = 0x01000000, /**< Right Height in Rear */ + OMX_AUDIO_DTSSPEAKERMASK_Clf = 0x02000000, /**< Low Center in Front */ + OMX_AUDIO_DTSSPEAKERMASK_Llf = 0x04000000, /**< Low Left in Front */ + OMX_AUDIO_DTSSPEAKERMASK_Rlf = 0x08000000, /**< Low Right in Front */ + OMX_AUDIO_DTSSPEAKERMASK_Lt = 0x10000000, + OMX_AUDIO_DTSSPEAKERMASK_Rt = 0x20000000 +} OMX_AUDIO_DTS_SPEAKERTYPE; + + +/* Extension to OMX_INDEXTYPE */ +enum +{ + OMX_IndexParamAudioDTSDec = OMX_IndexVendorStartUnused + 0x1, /**< reference: OMX_AUDIO_PARAM_DTSDECTYPE */ +#ifndef NOCODEFOR_CDEC_DSEC + OMX_IndexParamAudioDTSDecKey = OMX_IndexVendorStartUnused + 0x2, +#endif /* #ifndef NOCODEFOR_CDEC_DSEC */ +}; + + +typedef struct OMX_AUDIO_PARAM_DTSDECTYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to set. Must be input port. */ + + /* directive variables */ + + OMX_U32 nExSSID; /**< ExSS Id from which audio presentation is selected, 0~3. Default is 0. */ + OMX_U32 nAudioPresentIndex; /**< Audio presentation index, 0~7. Default is 0. */ + OMX_U32 nDRCPercent; /**< Percentage of DRC to be applied, 0~100. Default is 0. */ + OMX_BOOL bDialNorm; /**< Enable or disable dialog normalization. Default is OMX_TRUE. */ + OMX_AUDIO_DTS_SPKROUTTYPE nSpkrOut; /**< Requested speaker mask. Default is DTSSPKROUT_MASK_LR. + Actual output speaker mask depends on input bit stream, may be different from this requested one. + See OMX_GetParameter, OMX_IndexParamAudioPcm and OMX_AUDIO_PARAM_PCMMODETYPE. */ + OMX_BOOL bMixLFEIntoFront; /**< Enable or disable mixing LFE into front channels. Default is OMX_FALSE. */ + OMX_U32 nOutputBitWidth ; /**< Output PCM bit width, 24 or 16. Default is 16. + It determines nBitPerSample in OMX_AUDIO_PARAM_PCMMODETYPE */ + + /* informative variables, read only */ + + OMX_U32 nMaxSampleRate; /**< Maximum sample rate of the stream. Decoded sample rate is reported in OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_U32 nSamplesInFrameAtMaxSR; /**< Frame size at maximum sample rate. */ + OMX_U32 nMaxNumChannels; /**< Maximum number of channels in the stream. Decoded channles are reported in OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_AUDIO_DTS_SPEAKERTYPE nMaxChannelMask; /**< Maximum channel mask in the stream. See OMX_AUDIO_DTS_SPEAKERTYPE */ + OMX_U32 nRepTypes; /** Representation type, 1: unmapped, 2:LT_RT, 4:LH_RH */ +} OMX_AUDIO_PARAM_DTSDECTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk index d16d5df1204..fd3a4b51bc1 100644 --- a/media/libstagefright/omx/Android.mk +++ b/media/libstagefright/omx/Android.mk @@ -36,6 +36,10 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true) endif endif +ifeq ($(DTS_CODEC_M_), true) + LOCAL_CFLAGS += -DDTS_CODEC_M_ +endif + LOCAL_MODULE:= libstagefright_omx LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp index 5117dddc983..13605a7ffae 100755 --- a/media/libstagefright/omx/SoftOMXPlugin.cpp +++ b/media/libstagefright/omx/SoftOMXPlugin.cpp @@ -31,6 +31,24 @@ * See the License for the specific language governing permissions and * limitations under the License. * + ** + ** This file was modified by DTS, Inc. The portions of the + ** code that are surrounded by "DTS..." are copyrighted and + ** licensed separately, as follows: + ** + ** (C) 2015 DTS, Inc. + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License */ //#define LOG_NDEBUG 0 @@ -86,6 +104,9 @@ static const struct { { "OMX.dolby.eac3.decoder", "ddpdec", "audio_decoder.eac3" }, { "OMX.dolby.eac3_joc.decoder", "ddpdec", "audio_decoder.eac3_joc" }, #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + { "OMX.DTS.audio_decoder.dts", "dtsdec", "audio_decoder.dts" }, +#endif }; static const size_t kNumComponents = From a827736338330c92a9642c2a2cccb48ec0d9b1af Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Thu, 19 Nov 2015 13:49:18 +0800 Subject: [PATCH 05/32] audio: QTI resampler supports for 32 bit input format Configure QTI resampler as 32 bit input format to avoid losing precision. audioflinger: add channel count check to use QTI resampler Change-Id: I8f76dd82b72a0dd8b77343e77e0d0545e1be2114 CRs-Fixed: 940287 Change-Id: I7e1b8582cd6bb106ab0bd25f9bc1bd9e4092318b --- services/audioflinger/AudioMixer.cpp | 3 ++- services/audioflinger/AudioResamplerQTI.cpp | 21 +++++++++++++-------- services/audioflinger/AudioResamplerQTI.h | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 27a2f6542ef..5dcd399c962 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -785,7 +785,8 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam #ifdef QTI_RESAMPLER if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) && (trackSampleRate > devSampleRate * 2) && - ((devSampleRate == 48000)||(devSampleRate == 44100))) { + ((devSampleRate == 48000)||(devSampleRate == 44100)) && + (resamplerChannelCount <= 2)) { quality = AudioResampler::QTI_QUALITY; } #endif diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp index 44b741e7265..0d57e09f451 100644 --- a/services/audioflinger/AudioResamplerQTI.cpp +++ b/services/audioflinger/AudioResamplerQTI.cpp @@ -51,8 +51,9 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, { int16_t vl = mVolume[0]; int16_t vr = mVolume[1]; - int16_t *pBuf; + int32_t *pBuf; + int64_t tempL, tempR; size_t inFrameRequest; size_t inFrameCount = getNumInSample(outFrameCount); size_t index = 0; @@ -74,7 +75,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, if(mResamplerOutBuf) { delete [] mResamplerOutBuf; } - mTmpBuf = new int16_t[inFrameRequest + 16]; + mTmpBuf = new int32_t[inFrameRequest + 16]; mResamplerOutBuf = new int32_t[out_count]; } @@ -95,7 +96,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount) { provider->releaseBuffer(&mBuffer); @@ -121,8 +122,8 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); - pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); + pBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount * 2) { provider->releaseBuffer(&mBuffer); } @@ -133,8 +134,12 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, resample_exit: for (int i = 0; i < out_count; i += 2) { - fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl); - fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr); + // Multiplying q4.27 data with u4.12 gain could result in 39 fractional bit data(27+12) + // To get back the 27 fractional bit format output data, do right shift by 12 + tempL = (int64_t)mResamplerOutBuf[i] * vl; + tempR = (int64_t)mResamplerOutBuf[i+1] * vr; + fout[i] += float_from_q4_27((int32_t)(tempL>>12)); + fout[i+1] += float_from_q4_27((int32_t)(tempR>>12)); } mFrameIndex = frameIndex; @@ -151,7 +156,7 @@ void AudioResamplerQTI::setSampleRate(int32_t inSampleRate) void AudioResamplerQTI::init() { - QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate); + QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate, 1/*32bit in*/); } size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount) diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h index 0b30a9f6223..1cf93fc56d5 100644 --- a/services/audioflinger/AudioResamplerQTI.h +++ b/services/audioflinger/AudioResamplerQTI.h @@ -35,7 +35,7 @@ class AudioResamplerQTI : public AudioResampler { size_t getNumInSample(size_t outFrameCount); int16_t *mState; - int16_t *mTmpBuf; + int32_t *mTmpBuf; int32_t *mResamplerOutBuf; size_t mFrameIndex; size_t stateSize; From 78b3fb29b7b4629d73e96d1f396cd966882cdbb0 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Thu, 17 Dec 2015 11:27:28 -0800 Subject: [PATCH 06/32] Revert "NuPlayerDecoder: add synchronous call pause() to ensure decoder will not request or send out data." This reverts commit cd61d26973ee40948a32f1d3e190191e5265acfe. CRs-Fixed: 950212 Change-Id: I9bd79b14614df97208981f8ea064d4ec74a5c075 --- .../nuplayer/NuPlayer.cpp | 1 - .../nuplayer/NuPlayerDecoder.cpp | 1 + .../nuplayer/NuPlayerDecoder.h | 1 + .../nuplayer/NuPlayerDecoderBase.cpp | 19 ------------------- .../nuplayer/NuPlayerDecoderBase.h | 5 ----- .../nuplayer/NuPlayerDecoderPassThrough.cpp | 1 + 6 files changed, 3 insertions(+), 25 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 09909b5f733..e8583553274 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1143,7 +1143,6 @@ void NuPlayer::onMessageReceived(const sp &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); ALOGV("Tear down audio with reason %d.", reason); - mAudioDecoder->pause(); mAudioDecoder.clear(); ++mAudioDecoderGeneration; bool needsToCreateAudioDecoder = true; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index feef31170b0..51cd2fde65f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -93,6 +93,7 @@ NuPlayer::Decoder::Decoder( mIsSecure(false), mFormatChangePending(false), mTimeChangePending(false), + mPaused(true), mResumePending(false), mComponentName("decoder") { mCodecLooper = new ALooper; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index ba25041c4e3..19996151340 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -110,6 +110,7 @@ struct NuPlayer::Decoder : public DecoderBase { bool mFormatChangePending; bool mTimeChangePending; + bool mPaused; bool mResumePending; AString mComponentName; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp index 04bb61cdef0..7e7684202b6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp @@ -31,7 +31,6 @@ namespace android { NuPlayer::DecoderBase::DecoderBase(const sp ¬ify) : mNotify(notify), mBufferGeneration(0), - mPaused(false), mStats(new AMessage), mRequestInputBuffersPending(false) { // Every decoder has its own looper because MediaCodec operations @@ -84,13 +83,6 @@ void NuPlayer::DecoderBase::setRenderer(const sp &renderer) { msg->post(); } -void NuPlayer::DecoderBase::pause() { - sp msg = new AMessage(kWhatPause, this); - - sp response; - PostAndAwaitResponse(msg, &response); -} - status_t NuPlayer::DecoderBase::getInputBuffers(Vector > *buffers) const { sp msg = new AMessage(kWhatGetInputBuffers, this); msg->setPointer("buffers", buffers); @@ -154,17 +146,6 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp &msg) { break; } - case kWhatPause: - { - sp replyID; - CHECK(msg->senderAwaitsResponse(&replyID)); - - mPaused = true; - - (new AMessage)->postReply(replyID); - break; - } - case kWhatGetInputBuffers: { sp replyID; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h index a334ec57ec7..b0dc01da339 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h @@ -36,9 +36,6 @@ struct NuPlayer::DecoderBase : public AHandler { void init(); void setParameters(const sp ¶ms); - // Synchronous call to ensure decoder will not request or send out data. - void pause(); - void setRenderer(const sp &renderer); virtual status_t setVideoSurface(const sp &) { return INVALID_OPERATION; } @@ -81,7 +78,6 @@ struct NuPlayer::DecoderBase : public AHandler { sp mNotify; int32_t mBufferGeneration; - bool mPaused; sp mStats; private: @@ -89,7 +85,6 @@ struct NuPlayer::DecoderBase : public AHandler { kWhatConfigure = 'conf', kWhatSetParameters = 'setP', kWhatSetRenderer = 'setR', - kWhatPause = 'paus', kWhatGetInputBuffers = 'gInB', kWhatRequestInputBuffers = 'reqB', kWhatFlush = 'flus', diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp index daee3858073..9a22165854f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp @@ -48,6 +48,7 @@ NuPlayer::DecoderPassThrough::DecoderPassThrough( // The offload read buffer size is 32 KB but 24 KB uses less power. mAggregateBufferSizeBytes(24 * 1024), mSkipRenderingUntilMediaTimeUs(-1ll), + mPaused(false), mReachedEOS(true), mPendingAudioErr(OK), mPendingBuffersToDrain(0), From 238fb6bde4587d69f5f48c196a091d271796ee59 Mon Sep 17 00:00:00 2001 From: Paramananda Pradhan Date: Thu, 10 Dec 2015 18:42:09 +0530 Subject: [PATCH 07/32] drm : Give permission to access drm service api from Oma Drm engine Uses user defined permission "com.oma.drm.permission.ACCESS_OMA_DRM" to access protected api call from Oma Drm util framework. This changes is required for DRM Image support in Android. CRs-Fixed: 941545 Change-Id: If9b7d079612453f51e3e9e9126dd6553e73b8a5a --- drm/drmserver/DrmManagerService.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp index 857d73ecb02..df08f3253cd 100644 --- a/drm/drmserver/DrmManagerService.cpp +++ b/drm/drmserver/DrmManagerService.cpp @@ -93,6 +93,9 @@ bool DrmManagerService::isProtectedCallAllowed(drm_perm_t perm) { return selinuxIsProtectedCallAllowed(spid, perm); } } + if (checkCallingPermission(String16("com.oma.drm.permission.ACCESS_OMA_DRM")) == true) { + return true; + } return false; } From 4f333a26ab8dd1e58440bb56c56b803752f9c9f9 Mon Sep 17 00:00:00 2001 From: Sai Kumar Sanagavarapu Date: Mon, 21 Dec 2015 15:51:03 +0530 Subject: [PATCH 08/32] cameraservice: Change the error mapping for ERROR_CAMERA_DEVICE. In case of API1-HAL3, if HAL reports CAMERA3_MSG_ERROR_DEVICE, it is getting mapped to CAMERA_ERROR_UNKNOWN in the service layer. But this particular error code is not handled properly even in applications like GoogleCamera (Android default camera app). For example if camera deamon gets killed when GoogleCamera is previewing, since its not handling the error properly, preview freeze is seen for long time followed by mediaserver crash if any user interaction happens meanwhile. Ideally, app should close gracefully based on the error received. So, map CAMERA3_MSG_ERROR_DEVICE to CAMERA_ERROR_SERVER_DIED, so that app and mediaserver gets closed gracefully. Change-Id: Idad9d23262e28e85b020b5bacdaad7c77fe16372 --- services/camera/libcameraservice/api1/Camera2Client.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index 4338d641b04..18216362974 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -1741,8 +1741,6 @@ void Camera2Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCod err = CAMERA_ERROR_RELEASED; break; case ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE: - err = CAMERA_ERROR_UNKNOWN; - break; case ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE: err = CAMERA_ERROR_SERVER_DIED; break; From b997d6c67ae9c8143cf89f8c52b4dec4cb3e3abc Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Mon, 21 Dec 2015 16:39:11 +0530 Subject: [PATCH 09/32] audio: Update anchor time for offload playback post resume -AV sync is lost after multiple pasue/resume operatins. -Renderer does not update anchor time post resume and it may lead to AV sync loss after multiple pause/resume in offload playback case. -Get renderer position and update anchor time post resume for offload audio Change-Id: I2d9ba21c0e9b193ec77213de12229407cbf8dfd6 --- media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 159f0eeda5c..403473d5647 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -1537,6 +1537,13 @@ void NuPlayer::Renderer::onResume() { ALOGE("cannot start AudioSink err %d", err); notifyAudioTearDown(); } + //Update anchor time after resuming playback. + if (offloadingAudio()) { + int64_t nowUs = ALooper::GetNowUs(); + int64_t nowMediaUs = + mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs); + mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX); + } } { From e9a1b52f89c04530743fe6d8d16803115793c8e8 Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Wed, 18 Nov 2015 15:45:06 -0800 Subject: [PATCH 10/32] NuPlayerDecoder: add synchronous call pause() To ensure decoder will not request or send out data. Port of AOSP commit: 3bc667014875aba35102941b3997d242c303aa0d Bug: 25372978 was change-id Id66ab9b9961d5a3b9fb783ae73c27ed1c8054db8 CRs-Fixed: 950212 Change-Id: I3343c5bf244885c4cbbe040192573e6d75c01d6a --- .../nuplayer/NuPlayer.cpp | 1 + .../nuplayer/NuPlayerDecoder.cpp | 1 - .../nuplayer/NuPlayerDecoder.h | 1 - .../nuplayer/NuPlayerDecoderBase.cpp | 19 +++++++++++++++++++ .../nuplayer/NuPlayerDecoderBase.h | 5 +++++ .../nuplayer/NuPlayerDecoderPassThrough.cpp | 1 - .../nuplayer/NuPlayerDecoderPassThrough.h | 3 +-- 7 files changed, 26 insertions(+), 5 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index e8583553274..09909b5f733 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1143,6 +1143,7 @@ void NuPlayer::onMessageReceived(const sp &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); ALOGV("Tear down audio with reason %d.", reason); + mAudioDecoder->pause(); mAudioDecoder.clear(); ++mAudioDecoderGeneration; bool needsToCreateAudioDecoder = true; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 51cd2fde65f..feef31170b0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -93,7 +93,6 @@ NuPlayer::Decoder::Decoder( mIsSecure(false), mFormatChangePending(false), mTimeChangePending(false), - mPaused(true), mResumePending(false), mComponentName("decoder") { mCodecLooper = new ALooper; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index 19996151340..ba25041c4e3 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -110,7 +110,6 @@ struct NuPlayer::Decoder : public DecoderBase { bool mFormatChangePending; bool mTimeChangePending; - bool mPaused; bool mResumePending; AString mComponentName; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp index 7e7684202b6..04bb61cdef0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp @@ -31,6 +31,7 @@ namespace android { NuPlayer::DecoderBase::DecoderBase(const sp ¬ify) : mNotify(notify), mBufferGeneration(0), + mPaused(false), mStats(new AMessage), mRequestInputBuffersPending(false) { // Every decoder has its own looper because MediaCodec operations @@ -83,6 +84,13 @@ void NuPlayer::DecoderBase::setRenderer(const sp &renderer) { msg->post(); } +void NuPlayer::DecoderBase::pause() { + sp msg = new AMessage(kWhatPause, this); + + sp response; + PostAndAwaitResponse(msg, &response); +} + status_t NuPlayer::DecoderBase::getInputBuffers(Vector > *buffers) const { sp msg = new AMessage(kWhatGetInputBuffers, this); msg->setPointer("buffers", buffers); @@ -146,6 +154,17 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp &msg) { break; } + case kWhatPause: + { + sp replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + + mPaused = true; + + (new AMessage)->postReply(replyID); + break; + } + case kWhatGetInputBuffers: { sp replyID; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h index b0dc01da339..a334ec57ec7 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h @@ -36,6 +36,9 @@ struct NuPlayer::DecoderBase : public AHandler { void init(); void setParameters(const sp ¶ms); + // Synchronous call to ensure decoder will not request or send out data. + void pause(); + void setRenderer(const sp &renderer); virtual status_t setVideoSurface(const sp &) { return INVALID_OPERATION; } @@ -78,6 +81,7 @@ struct NuPlayer::DecoderBase : public AHandler { sp mNotify; int32_t mBufferGeneration; + bool mPaused; sp mStats; private: @@ -85,6 +89,7 @@ struct NuPlayer::DecoderBase : public AHandler { kWhatConfigure = 'conf', kWhatSetParameters = 'setP', kWhatSetRenderer = 'setR', + kWhatPause = 'paus', kWhatGetInputBuffers = 'gInB', kWhatRequestInputBuffers = 'reqB', kWhatFlush = 'flus', diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp index 9a22165854f..daee3858073 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp @@ -48,7 +48,6 @@ NuPlayer::DecoderPassThrough::DecoderPassThrough( // The offload read buffer size is 32 KB but 24 KB uses less power. mAggregateBufferSizeBytes(24 * 1024), mSkipRenderingUntilMediaTimeUs(-1ll), - mPaused(false), mReachedEOS(true), mPendingAudioErr(OK), mPendingBuffersToDrain(0), diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h index 629e266e77e..52fff73f152 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h @@ -54,8 +54,7 @@ struct NuPlayer::DecoderPassThrough : public DecoderBase { sp mRenderer; size_t mAggregateBufferSizeBytes; int64_t mSkipRenderingUntilMediaTimeUs; - bool mPaused; - bool mReachedEOS; + bool mReachedEOS; // Used by feedDecoderInputData to aggregate small buffers into // one large buffer. From 48fe40328663cc5d398c96895b893ee2373a329f Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Tue, 22 Dec 2015 17:07:21 +0530 Subject: [PATCH 11/32] libstagefright:Fix random memcmp crash while accessing output format. Random memcmp crash happens while checking for image-data in output format of audio buffer.Audio output format gets updated with pcm-format flag after codec formatchange in ExtendedNuUtils. Simultaneous memory check happens for image-data in FBD of MediaCodec. So crash happens. Avoid checking for image-data and crop information for audio buffers. Change-Id: I85ffcb149dc67a0f1bdb26116245627b1843d932 --- media/libstagefright/MediaCodec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 485331b1e31..c4f4389356f 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -2569,7 +2569,7 @@ ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { info->mOwnedByClient = true; // set image-data - if (info->mFormat != NULL) { + if (info->mFormat != NULL && mIsVideo) { sp imageData; if (info->mFormat->findBuffer("image-data", &imageData)) { info->mData->meta()->setBuffer("image-data", imageData); From 23c8307e06627c1f045e61f2d6287a974987a524 Mon Sep 17 00:00:00 2001 From: Mingming Yin Date: Tue, 22 Dec 2015 12:12:00 -0800 Subject: [PATCH 12/32] libmedia: correct latency computing for TRANSFER_SYNC - Compute the track latency by frame count returned from audio hal when in TRANSFER_SYNC mode Change-Id: If7bbf780abc8e141eb35eea44c01c583b1290d3c --- media/libmedia/AudioRecord.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index a6d2e83ae68..fc35a4cacc5 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -276,7 +276,8 @@ status_t AudioRecord::set( mActive = false; mUserData = user; // TODO: add audio hardware input latency here - if (mTransfer == TRANSFER_CALLBACK) { + if (mTransfer == TRANSFER_CALLBACK || + mTransfer == TRANSFER_SYNC) { mLatency = (1000*mNotificationFramesAct) / sampleRate; } else { mLatency = (1000*mFrameCount) / sampleRate; From b10a3f02a0313f273c8ec6670b906da7ad05833f Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Wed, 23 Dec 2015 17:54:33 -0800 Subject: [PATCH 13/32] frameworks/av: Fix LOG_NDEBUG compilation issues Fix compilation issues that appear when enabling LOG_NDEBUG. Change-Id: I87e9e5ac66157759dd6f521fab0dd346089a011a --- media/libmediaplayerservice/nuplayer/StreamingSource.cpp | 4 +++- media/libstagefright/rtsp/MyHandler.h | 2 ++ services/audioflinger/FastCapture.cpp | 1 + services/audioflinger/FastCaptureDumpState.cpp | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index 0246b59f81a..aa47db395b6 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -18,6 +18,8 @@ #define LOG_TAG "StreamingSource" #include +#include + #include "StreamingSource.h" #include "ATSParser.h" @@ -248,7 +250,7 @@ status_t NuPlayer::StreamingSource::dequeueAccessUnit( if (err == OK) { int64_t timeUs; CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); - ALOGV("dequeueAccessUnit timeUs=%lld us", timeUs); + ALOGV("dequeueAccessUnit timeUs=%" PRId64 " us", timeUs); } #endif diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 7290ee2585f..70063b1a9b7 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -18,7 +18,9 @@ #define MY_HANDLER_H_ +#ifndef LOG_NDEBUG //#define LOG_NDEBUG 0 +#endif #ifndef LOG_TAG #define LOG_TAG "MyHandler" diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp index 1bba5f651ec..952de7fef07 100644 --- a/services/audioflinger/FastCapture.cpp +++ b/services/audioflinger/FastCapture.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "AudioFlinger.h" #include "FastCapture.h" namespace android { diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/FastCaptureDumpState.cpp index 53eeba59d59..de4a6db1528 100644 --- a/services/audioflinger/FastCaptureDumpState.cpp +++ b/services/audioflinger/FastCaptureDumpState.cpp @@ -15,7 +15,7 @@ */ #define LOG_TAG "FastCaptureDumpState" -//define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include "Configuration.h" #include From 415bcac8afac7aef3e9853cfe4a0f2a0eb2f04ad Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Thu, 24 Dec 2015 19:58:54 +0530 Subject: [PATCH 14/32] AudioMixer: delete reformatBuffer provider in proper order If mixer is creating reformatBufferProvider and downMixerBufferProvider while adding a track it first creates downMixerProvider then reformatBufferProvider. While deleting track it first deletes downMixerBufferProvider and then reformatBufferProvider, which should be in reverse order, the object created last should be deleted first. Change-Id: I844e7862280fe37c3167b31e92bbb27aa9463315 --- services/audioflinger/AudioMixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 27a2f6542ef..b830985e788 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -445,10 +445,10 @@ void AudioMixer::deleteTrackName(int name) // delete the resampler delete track.resampler; track.resampler = NULL; - // delete the downmixer - mState.tracks[name].unprepareForDownmix(); // delete the reformatter mState.tracks[name].unprepareForReformat(); + // delete the downmixer + mState.tracks[name].unprepareForDownmix(); // delete the timestretch provider delete track.mTimestretchBufferProvider; track.mTimestretchBufferProvider = NULL; From 4f7c4df058bf1dcce564b8d27cee55bb3f70c473 Mon Sep 17 00:00:00 2001 From: Kim Zhang Date: Tue, 29 Dec 2015 14:50:52 +0800 Subject: [PATCH 15/32] StagefrightMetadataRetriever: correct the status flag In case of EOS or ERROR from source, correct the status flag and clear the input index to continue to wait for output buffer from decoder. This is to fix thumbnail generation failure for some clips with one frame. CRs-Fixed: 951250 Change-Id: If9889dbcc32bf49368add408a317da026879fec8 --- media/libstagefright/StagefrightMetadataRetriever.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 5a8f6a58d0b..45d22d59f27 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -271,6 +271,9 @@ static VideoFrame *extractVideoFrame( if (err != OK) { ALOGW("Input Error or EOS"); haveMoreInputs = false; + //correct the status to continue to get output from decoder + err = OK; + inputIndex = -1; break; } From 0e0777f64781406d434e9a7a8f6542be504a17cb Mon Sep 17 00:00:00 2001 From: Santhosh Behara Date: Wed, 25 Nov 2015 19:27:22 +0530 Subject: [PATCH 16/32] ACodec: update native window crop rectangle In setupNativeWindowSizeFormatAndUsage, set the crop rectangle with the output port's crop value. Change-Id: I415be069d02d88dcd6b7c2460dda6df191ee7434 --- media/libstagefright/ACodec.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 677e2d7a266..d9575d3a0c9 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -933,13 +933,31 @@ status_t ACodec::setupNativeWindowSizeFormatAndUsage( *finalUsage = usage; ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); - return setNativeWindowSizeFormatAndUsage( + err = setNativeWindowSizeFormatAndUsage( nativeWindow, def.format.video.nFrameWidth, def.format.video.nFrameHeight, def.format.video.eColorFormat, mRotationDegrees, usage); + if (err == OK) { + OMX_CONFIG_RECTTYPE rect; + InitOMXParams(&rect); + rect.nPortIndex = kPortIndexOutput; + err = mOMX->getConfig( + mNode, OMX_IndexConfigCommonOutputCrop, &rect, sizeof(rect)); + if (err == OK) { + ALOGV("rect size = %d, %d, %d, %d", rect.nLeft, rect.nTop, rect.nWidth, rect.nHeight); + android_native_rect_t crop; + crop.left = rect.nLeft; + crop.top = rect.nTop; + crop.right = rect.nLeft + rect.nWidth - 1; + crop.bottom = rect.nTop + rect.nHeight - 1; + ALOGV("crop update (%d, %d), (%d, %d)", crop.left, crop.top, crop.right, crop.bottom); + err = native_window_set_crop(nativeWindow, &crop); + } + } + return err; } status_t ACodec::configureOutputBuffersFromNativeWindow( From 1577bd0c056bdc2c293b74e32a081f2020dba419 Mon Sep 17 00:00:00 2001 From: Shivaprasad Hongal Date: Fri, 11 Dec 2015 15:00:51 -0800 Subject: [PATCH 17/32] ACodec: Fix error handling in OutputPortSettingsChangedState Freeing the input buffers & node in ACodec::OutputPortSettingsChangedState on error, can cause NuPlayerDecoder to deference freed buffers. Instead of freeing the node internally on error in OutputPortSettingsChangedState, notify error to NuPlayer, and add kWhatShutDown handling to initiate Idle state transition. Change-Id: I7778d759c564fad27d266ac63d293bf0c30c029b --- media/libstagefright/ACodec.cpp | 37 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 677e2d7a266..e550602532d 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -6516,8 +6516,34 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( bool handled = false; switch (msg->what()) { - case kWhatFlush: case kWhatShutdown: + { + int32_t keepComponentAllocated; + CHECK(msg->findInt32( + "keepComponentAllocated", &keepComponentAllocated)); + + mCodec->mShutdownInProgress = true; + mCodec->mExplicitShutdown = true; + mCodec->mKeepComponentAllocated = keepComponentAllocated; + + status_t err = mCodec->mOMX->sendCommand( + mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); + if (err != OK) { + if (keepComponentAllocated) { + mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); + } + // TODO: do some recovery here. + } else { + // This is technically not correct, but appears to be + // the only way to free the component instance using + // ExectingToIdleState. + mCodec->changeState(mCodec->mExecutingToIdleState); + } + + handled = true; + break; + } + case kWhatFlush: case kWhatResume: case kWhatSetParameters: { @@ -6584,15 +6610,6 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( if (err != OK) { mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); - - // This is technically not correct, but appears to be - // the only way to free the component instance. - // Controlled transitioning from excecuting->idle - // and idle->loaded seem impossible probably because - // the output port never finishes re-enabling. - mCodec->mShutdownInProgress = true; - mCodec->mKeepComponentAllocated = false; - mCodec->changeState(mCodec->mLoadedState); } return true; From b1f2a05a34451111fac304907de08a9e2911af9d Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Wed, 6 Jan 2016 15:49:06 +0800 Subject: [PATCH 18/32] nuplayer: looping playback only if it was running Audio buffer filling in renderer is still happening, though pause was issued. As a result, EOS was reported irrespective of renderer state. If nuplayer driver receives playback complete after stopped, it will again be activated, which appears stop is not taking effect. Add a check for driver state to allow looping only if it was in running state. Change-Id: Ic9f8eac635a774cd805b3978fab640d73ae35744 CRs-Fixed: 958311 --- .../nuplayer/NuPlayerDriver.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 716c3534388..c71957e8683 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -747,12 +747,19 @@ void NuPlayerDriver::notifyListener_l( } } if (mLooping || mAutoLoop) { - mPlayer->seekToAsync(0); - if (mAudioSink != NULL) { - // The renderer has stopped the sink at the end in order to play out - // the last little bit of audio. If we're looping, we need to restart it. - mAudioSink->start(); + if (mState == STATE_RUNNING) { + mPlayer->seekToAsync(0); + if (mAudioSink != NULL) { + // The renderer has stopped the sink at the end in order to play out + // the last little bit of audio. If we're looping, we need to restart it. + mAudioSink->start(); + } + } else { + mPlayer->pause(); + mState = STATE_PAUSED; + mAtEOS = true; } + // don't send completion event when looping return; } From bff544f01922cc44a331d074ef33130ac6741252 Mon Sep 17 00:00:00 2001 From: Alexy Joseph Date: Thu, 7 Jan 2016 17:17:44 -0800 Subject: [PATCH 19/32] mpeg2ts: Add support for DTSHD HLS streaming Signed-off-by: Amal Paul (cherry picked from commit b77061ff629fae8ac1f721aa48cb61ced058394e) Conflicts: media/libstagefright/mpeg2ts/ATSParser.cpp media/libstagefright/mpeg2ts/ATSParser.h media/libstagefright/mpeg2ts/ESQueue.cpp media/libstagefright/mpeg2ts/ESQueue.h media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp Change-Id: Ie081bc5b1febddc5b6ac9536af9cecddc6fc1192 --- media/libstagefright/mpeg2ts/ATSParser.cpp | 15 ++ media/libstagefright/mpeg2ts/ATSParser.h | 4 + media/libstagefright/mpeg2ts/Android.mk | 4 + media/libstagefright/mpeg2ts/ESQueue.cpp | 182 ++++++++++++++++++ media/libstagefright/mpeg2ts/ESQueue.h | 11 ++ .../mpeg2ts/MPEG2PSExtractor.cpp | 6 + 6 files changed, 222 insertions(+) diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index fb30643ba4b..02eab8dfd95 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -18,6 +18,11 @@ * licensed separately, as follows: * * (C) 2011-2015 Dolby Laboratories, Inc. + * This file was modified by DTS, Inc. The portions of the + * code that are surrounded by "DTS..." are copyrighted and + * licensed separately, as follows: + * + * (C) 2015 DTS, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -666,6 +671,13 @@ ATSParser::Stream::Stream( ElementaryStreamQueue::METADATA); break; +#ifdef DTS_CODEC_M_ + case STREAMTYPE_DTSHD: + mQueue = new ElementaryStreamQueue( + ElementaryStreamQueue::DTSHD); + break; +#endif + default: break; } @@ -788,6 +800,9 @@ bool ATSParser::Stream::isAudio() const { #ifdef DOLBY_ENABLE case STREAMTYPE_EAC3: #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + case STREAMTYPE_DTSHD: +#endif return true; default: diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 47f0353d68d..0cc815473d5 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -157,6 +157,10 @@ struct ATSParser : public RefBase { #ifdef DOLBY_ENABLE STREAMTYPE_EAC3 = 0x87, #endif // DOLBY_END +#ifdef DTS_CODEC_M_ + // Stream type 0x06 for all DTS streams (including DTSHD) + STREAMTYPE_DTSHD = 0x06, +#endif }; protected: diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk index 72cf6254198..24ead80b5a5 100644 --- a/media/libstagefright/mpeg2ts/Android.mk +++ b/media/libstagefright/mpeg2ts/Android.mk @@ -17,6 +17,10 @@ LOCAL_C_INCLUDES:= \ LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true +ifeq ($(DTS_CODEC_M_), true) + LOCAL_CFLAGS += -DDTS_CODEC_M_ +endif + LOCAL_MODULE:= libstagefright_mpeg2ts ifeq ($(TARGET_ARCH),arm) diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index 754cffe8dd4..9b5f5d93d0b 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -18,6 +18,7 @@ * licensed separately, as follows: * * (C) 2011-2015 Dolby Laboratories, Inc. + * (C) 2015 DTS, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -199,6 +200,107 @@ static bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) { return parseAC3SyncFrame(ptr, size, NULL) > 0; } +#ifdef DTS_CODEC_M_ +// Parse DTS header assuming the current ptr is start position of syncframe, +// update metadata only if applicable, and return the payload size +static unsigned parseDTSSyncFrame( + const uint8_t *ptr, size_t size, sp *metaData) { + + #define DTS_SYNCWORD_CORE 0x7FFE8001 + #define DTS_SYNCWORD_SUBSTREAM 0x64582025 + #define DTS_SYNCWORD_LBR 0x0a801921 + #define DTS_SYNCWORD_XLL 0x41a29547 + + ABitReader bits(ptr, size); + unsigned syncValue = 0; + static unsigned dtsChannelCount = 0; + static unsigned dtsSamplingRate = 0; + unsigned payloadSize = 0; + + // Check for DTS core or substream sync + if (bits.numBitsLeft() < 32) { + return 0; + } + + // Get the sync value + syncValue = bits.getBits(32); + if (!((syncValue == DTS_SYNCWORD_CORE) || + (syncValue == DTS_SYNCWORD_SUBSTREAM))){ + return 0; + } + + if(syncValue == DTS_SYNCWORD_CORE) { + // Stream with a core + if (bits.numBitsLeft() < 1 + 5 + 1 + 7 + 14 + 6 + 4) { //FTYPE(1) + SHORT(5) + CRC(1) + NBLKS(7) + FSIZE(14) + AMODE(6) + SFREQ(4) + ALOGV("DTSHD Not enough bits left for further parsing"); + return 0; + } + bits.skipBits(14); //FTYPE(1) + SHORT(5) + CRC(1) + NBLKS(7) + + // Get frame size + unsigned frameByteSize = bits.getBits(14) + 1; + payloadSize = frameByteSize; + ALOGV(" DTSHD Core Stream found with frame size = %d", frameByteSize); + + // Get channel count + static const unsigned dtsChannelCountTable[] = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8 }; + unsigned aMode = bits.getBits(6); + dtsChannelCount = (aMode < 16) ? dtsChannelCountTable[aMode] : 0; + + // Get sampling freq + static const unsigned samplingRateTable[] = { 0, 8000, 16000, 32000, 0, + 0, 11025, 22050, 44100, 0, + 0, 12000, 24000, 48000, 0, 0}; + unsigned srIndex = bits.getBits(4); + dtsSamplingRate = samplingRateTable[srIndex]; + + } else { + // Stream with extension substream + if (bits.numBitsLeft() < 2 + 2 + 1) { //UserDefinedBits(2) + nExtSSIndex(2) + bHeaderSizeType(1) + ALOGV("DTSHD Not enough bits left for further parsing"); + return 0; + } + bits.skipBits(4); //UserDefinedBits(2) + nExtSSIndex(2) + + unsigned bHeaderSizeType = bits.getBits(1); + unsigned numBits4Header = 0; + unsigned numBits4ExSSFsize = 0; + + if(bHeaderSizeType == 0) { + numBits4Header = 8; + numBits4ExSSFsize = 16; + } else { + numBits4Header = 12; + numBits4ExSSFsize = 20; + } + + if(bits.numBitsLeft() < numBits4Header + numBits4ExSSFsize) { + ALOGV("DTSHD Not enough bits left for further parsing"); + return 0; + } + unsigned numExtHeadersize = bits.getBits(numBits4Header) + 1; + unsigned numExtSSFsize = bits.getBits(numBits4ExSSFsize) + 1; + unsigned frameByteSize = numExtSSFsize + numExtHeadersize; + payloadSize = frameByteSize; + ALOGV(" DTSHD extension sub stream found with frame size = %d", frameByteSize); + dtsChannelCount = 8; + dtsSamplingRate = 48000; + } + + if (metaData != NULL) { + (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS); + (*metaData)->setInt32(kKeyChannelCount, dtsChannelCount); + (*metaData)->setInt32(kKeySampleRate, dtsSamplingRate); + } + + return payloadSize; +} + +static bool IsSeeminglyValidDTSHeader(const uint8_t *ptr, size_t size) { + return parseDTSSyncFrame(ptr, size, NULL) > 0; +} +#endif + static bool IsSeeminglyValidADTSHeader( const uint8_t *ptr, size_t size, size_t *frameLength) { if (size < 7) { @@ -478,6 +580,35 @@ status_t ElementaryStreamQueue::appendData( break; } +#ifdef DTS_CODEC_M_ + case DTSHD: + { + uint8_t *ptr = (uint8_t *)data; + + ssize_t startOffset = -1; + for (size_t i = 0; i < size; ++i) { + if (IsSeeminglyValidDTSHeader(&ptr[i], size - i)) { + startOffset = i; + break; + } + } + + if (startOffset < 0) { + return ERROR_MALFORMED; + } + + if (startOffset > 0) { + ALOGI("found something resembling an DTS Sync word at " + "syncword at offset %zd", + startOffset); + } + + data = &ptr[startOffset]; + size -= startOffset; + break; + } +#endif + default: ALOGE("Unknown mode: %d", mMode); return ERROR_MALFORMED; @@ -566,6 +697,10 @@ sp ElementaryStreamQueue::dequeueAccessUnit() { return dequeueAccessUnitPCMAudio(); case METADATA: return dequeueAccessUnitMetadata(); +#ifdef DTS_CODEC_M_ + case DTSHD: + return dequeueAccessUnitDTS(); +#endif default: if (mMode != MPEG_AUDIO) { ALOGE("Unknown mode"); @@ -624,6 +759,53 @@ sp ElementaryStreamQueue::dequeueAccessUnitAC3() { return accessUnit; } +#ifdef DTS_CODEC_M_ +sp ElementaryStreamQueue::dequeueAccessUnitDTS() { + unsigned syncStartPos = 0; // in bytes + unsigned payloadSize = 0; + sp format = new MetaData; + while (true) { + if (syncStartPos + 2 >= mBuffer->size()) { + return NULL; + } + + payloadSize = parseDTSSyncFrame( + mBuffer->data() + syncStartPos, + mBuffer->size() - syncStartPos, + &format); + if (payloadSize > 0) { + break; + } + ++syncStartPos; + } + + if (mBuffer->size() < syncStartPos + payloadSize) { + ALOGV("Not enough buffer size for DTSHD"); + return NULL; + } + + if (mFormat == NULL) { + mFormat = format; + } + + sp accessUnit = new ABuffer(syncStartPos + payloadSize); + memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize); + + int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize); + CHECK_GE(timeUs, 0ll); + accessUnit->meta()->setInt64("timeUs", timeUs); + + memmove( + mBuffer->data(), + mBuffer->data() + syncStartPos + payloadSize, + mBuffer->size() - syncStartPos - payloadSize); + + mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize); + + return accessUnit; +} +#endif + sp ElementaryStreamQueue::dequeueAccessUnitPCMAudio() { if (mBuffer->size() < 4) { return NULL; diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h index c6a9b89a202..50a3443c0bf 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.h +++ b/media/libstagefright/mpeg2ts/ESQueue.h @@ -18,6 +18,11 @@ * licensed separately, as follows: * * (C) 2011-2015 Dolby Laboratories, Inc. + * This file was modified by DTS, Inc. The portions of the + * code that are surrounded by "DTS..." are copyrighted and + * licensed separately, as follows: + * + * (C) 2015 DTS, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +69,9 @@ struct ElementaryStreamQueue { MPEG4_VIDEO, PCM_AUDIO, METADATA, +#ifdef DTS_CODEC_M_ + DTSHD, +#endif }; enum Flags { @@ -112,6 +120,9 @@ struct ElementaryStreamQueue { virtual sp dequeueAccessUnitH265() { return NULL; }; +#ifdef DTS_CODEC_M_ + sp dequeueAccessUnitDTS(); +#endif // consume a logical (compressed) access unit of size "size", // returns its timestamp in us (or -1 if no time information). diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp index 86645d5c25b..9554f957ba1 100644 --- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp @@ -18,6 +18,7 @@ * licensed separately, as follows: * * (C) 2011-2015 Dolby Laboratories, Inc. + * (C) 2015 DTS, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -625,6 +626,11 @@ MPEG2PSExtractor::Track::Track( case ATSParser::STREAMTYPE_MPEG2_AUDIO: mode = ElementaryStreamQueue::MPEG_AUDIO; break; +#ifdef DTS_CODEC_M_ + case ATSParser::STREAMTYPE_DTSHD: + mode = ElementaryStreamQueue::DTSHD; + break; +#endif #ifdef DOLBY_ENABLE case ATSParser::STREAMTYPE_AC3: From c2fe2d907dd8d0edf6b2857780092b9cde3f46ea Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 6 Jan 2016 17:03:22 -0800 Subject: [PATCH 20/32] SoftVorbis: memory access check Check for valid input buffer header before reading from it. This seems to be manifested only when memory map of an input buffer sent from a remote process fails in mediaserver context. For-CR: 916568 Change-Id: I4ee16e7104c2d8bf579f80201864009e51cd1b25 --- .../codecs/vorbis/dec/SoftVorbis.cpp | 14 +++++++++++++- .../libstagefright/codecs/vorbis/dec/SoftVorbis.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp index 3dc549eba9e..08200c183d8 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -56,7 +56,8 @@ SoftVorbis::SoftVorbis( mNumFramesLeftOnPage(-1), mSawInputEos(false), mSignalledOutputEos(false), - mOutputPortSettingsChange(NONE) { + mOutputPortSettingsChange(NONE), + mSignalledError(false) { initPorts(); CHECK_EQ(initDecoder(), (status_t)OK); } @@ -251,10 +252,21 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) { return; } + if (mSignalledError) { + return; + } + if (portIndex == 0 && mInputBufferCount < 2) { BufferInfo *info = *inQueue.begin(); OMX_BUFFERHEADERTYPE *header = info->mHeader; + if (!header || !header->pBuffer) { + ALOGE("b/25727575 has happened. report error"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + const uint8_t *data = header->pBuffer + header->nOffset; size_t size = header->nFilledLen; diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h index 1d00816971d..7decc5a6a8b 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h @@ -68,6 +68,8 @@ struct SoftVorbis : public SimpleSoftOMXComponent { AWAITING_ENABLED } mOutputPortSettingsChange; + bool mSignalledError; + void initPorts(); status_t initDecoder(); bool isConfigured() const; From e706146fab84fe44ad114d9e27bf9cbb9cd75dfd Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Wed, 23 Dec 2015 17:56:47 -0800 Subject: [PATCH 21/32] libavextensions: Add LOG_NDEBUG define LOG_NDEBUG is inherited indirectly from both MyHandler.h & Log.h if no LOG_NDEBUG is defined locally within AVMediaServiceUtils. Add a local definition to keep debug usage for this file straightforward. Change-Id: I878cdc747e8349e937b13dd27c738d45f99dee0a --- .../libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp index 0e423679b4b..5306a39d2ef 100644 --- a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013 - 2016, 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 @@ -28,6 +28,7 @@ */ #define LOG_TAG "AVMediaServiceUtils" +//#define LOG_NDEBUG 0 #include #include From df53ee8e710224edf787ae2658c619791452c82c Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Wed, 23 Dec 2015 12:22:18 -0800 Subject: [PATCH 22/32] audioflinger: Enable TEE_SINK compilation Change CHECK to ALOG_ASSERT to allow compilation of the TEE_SINK dump feature. Change-Id: I1114a9d185cfd24cdbdda51c526f48be7fd009f9 --- services/audioflinger/AudioFlinger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 59a0a460678..1a0a110d90b 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -3051,7 +3051,7 @@ void AudioFlinger::dumpTee(int fd, const sp& source, audio_io_hand bool firstRead = true; #define TEE_SINK_READ 1024 // frames per I/O operation void *buffer = malloc(TEE_SINK_READ * frameSize); - CHECK (buffer != NULL); + ALOG_ASSERT(buffer != NULL); for (;;) { size_t count = TEE_SINK_READ; ssize_t actual = teeSource->read(buffer, count, From a8d34bb9fde4d9e1f9070c7403321d3fdfee915c Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Tue, 27 Oct 2015 12:11:18 +0530 Subject: [PATCH 23/32] AudioMixer: Clear bufferProviders in correct order Issue: While switching between clips with different track properties, when earlier track is cleared, postDownMixerBufferProvider tries to release a buffer to serverProxy instead of the original owner i.e. downMixBufferProvider. This illegal releaseBuffer call to serverProxy results in an assert in AudioTrackShared. -In issue scenario, data flow path in AudioMixer is, ServerProxy-->-->DownMixer-->PostDownMixer-->Resampler, - Clear for downMixerBufferProvider ensures that all serverproxy buffers are returned back. -This also causes the postDownMixer to get connected with serverProxy. -Hence on delete of postDownMixer illegal releaseBuffer for serverProxy gets executed. Fix: Clear PostDownMixerBufferProvider before clearing DownMixerBufferProvider to ensure that buffers are release to right owners. Change-Id: I982366660d0a1e04be8cca6dabe758221dedf9b1 --- services/audioflinger/AudioMixer.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 28dd42aafba..2a237a85b45 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -308,6 +308,11 @@ bool AudioMixer::setChannelMasks(int name, void AudioMixer::track_t::unprepareForDownmix() { ALOGV("AudioMixer::unprepareForDownmix(%p)", this); + if (mPostDownmixReformatBufferProvider != NULL) { + delete mPostDownmixReformatBufferProvider; + mPostDownmixReformatBufferProvider = NULL; + reconfigureBufferProviders(); + } mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; if (downmixerBufferProvider != NULL) { // this track had previously been configured with a downmixer, delete it @@ -363,18 +368,9 @@ status_t AudioMixer::track_t::prepareForDownmix() void AudioMixer::track_t::unprepareForReformat() { ALOGV("AudioMixer::unprepareForReformat(%p)", this); - bool requiresReconfigure = false; if (mReformatBufferProvider != NULL) { delete mReformatBufferProvider; mReformatBufferProvider = NULL; - requiresReconfigure = true; - } - if (mPostDownmixReformatBufferProvider != NULL) { - delete mPostDownmixReformatBufferProvider; - mPostDownmixReformatBufferProvider = NULL; - requiresReconfigure = true; - } - if (requiresReconfigure) { reconfigureBufferProviders(); } } From 01b50b3476026dcb6968620ad4883351c597cd72 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Tue, 19 Jan 2016 17:32:00 +0530 Subject: [PATCH 24/32] Revert "AudioMixer: delete reformatBuffer provider in proper order" This reverts commit 415bcac8afac7aef3e9853cfe4a0f2a0eb2f04ad. Change-Id: Ibbc35f16ef8cd17ead72498178c3e7bca1dff3cc --- services/audioflinger/AudioMixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 2a237a85b45..bb9d4e59fcb 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -441,10 +441,10 @@ void AudioMixer::deleteTrackName(int name) // delete the resampler delete track.resampler; track.resampler = NULL; - // delete the reformatter - mState.tracks[name].unprepareForReformat(); // delete the downmixer mState.tracks[name].unprepareForDownmix(); + // delete the reformatter + mState.tracks[name].unprepareForReformat(); // delete the timestretch provider delete track.mTimestretchBufferProvider; track.mTimestretchBufferProvider = NULL; From 6c5a71f4903182eac5a0401ed1291aaa683c28c3 Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Tue, 26 Jan 2016 13:41:38 -0800 Subject: [PATCH 25/32] stagefright: Fix CLANG compilation for AMR decoder Fix invalid type in error log's format string. Change-Id: I26aabfcdc1a03c0a7d9cd10fb3b39a660a9be03a --- media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index f8316fd314c..1a4ed554f25 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -353,7 +353,7 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { size_t frameSize = getFrameSize(mode); if (inHeader->nFilledLen < frameSize) { - ALOGE("Filled length vs frameSize %u vs %lu. Corrupt clip?", + ALOGE("Filled length vs frameSize %u vs %zu. Corrupt clip?", inHeader->nFilledLen, frameSize); notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); From a3824f333cc89f1c1c0858f8c0e0ab5bed1aca82 Mon Sep 17 00:00:00 2001 From: Kim Zhang Date: Tue, 31 Mar 2015 13:56:10 +0800 Subject: [PATCH 26/32] libstagefright: add NULL check in MediaCodecSource's puller When CameraSource/AudioSource is stopped, puller will read a NULL buffer with success, so we should add NULL check before release it. Change-Id: I8924167fc79c7880e80115aafbb9cc7c3e9e885c CRs-Fixed: 813924 --- media/libstagefright/MediaCodecSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 925be14cb4e..aef67151a08 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -216,7 +216,7 @@ void MediaCodecSource::Puller::onMessageReceived(const sp &msg) { status_t err = mSource->read(&mbuf); if (mPaused) { - if (err == OK) { + if (err == OK && (NULL != mbuf)) { mbuf->release(); mbuf = NULL; } From dc93fb8804649aa9702a6df2607f07eb495c6d71 Mon Sep 17 00:00:00 2001 From: Surajit Podder Date: Mon, 1 Feb 2016 13:51:18 +0530 Subject: [PATCH 27/32] video: Add metadata support for DataSource Add meta() API to query and update DataSource metadata. Change-Id: Ibc99fbb6b9bdd6ca6a9d0b25883ba5907946a81d --- include/media/stagefright/DataSource.h | 8 ++++++-- media/libstagefright/DataSource.cpp | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 0c31e726bc7..a71285eb70f 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -27,10 +27,10 @@ #include #include #include +#include namespace android { -struct AMessage; struct AString; class IDataSource; struct IMediaHTTPService; @@ -57,7 +57,7 @@ class DataSource : public RefBase { static sp CreateMediaHTTP(const sp &httpService); static sp CreateFromIDataSource(const sp &source); - DataSource() {} + DataSource() : mMeta(new AMessage) {} virtual status_t initCheck() const = 0; @@ -108,10 +108,14 @@ class DataSource : public RefBase { virtual String8 getMIMEType() const; + virtual sp meta() { return mMeta; } + protected: virtual ~DataSource() {} private: + sp mMeta; + static Mutex gSnifferMutex; static List gSniffers; static bool gSniffersRegistered; diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index b5e7a6e7886..499abe94ecf 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include From d326a87d01ab88441b610b24e1fe868b863dff81 Mon Sep 17 00:00:00 2001 From: Santhosh Behara Date: Thu, 26 Nov 2015 15:27:50 +0530 Subject: [PATCH 28/32] ACodec: update the right size and crop in smooth streaming case In smooth streaming enabled case, the max width and max height sizes should be updated in native window. And the crop rectangle should also be updated. Change-Id: I4a15aa24a51b495141001dd43adec7005ab0c742 --- media/libstagefright/ACodec.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 80ea25d53d3..82a1fa64d47 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -956,10 +956,24 @@ status_t ACodec::setupNativeWindowSizeFormatAndUsage( *finalUsage = usage; ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); + int32_t width = 0, height = 0; + int32_t isAdaptivePlayback = 0; + + if (mInputFormat->findInt32("adaptive-playback", &isAdaptivePlayback) + && isAdaptivePlayback + && mInputFormat->findInt32("max-width", &width) + && mInputFormat->findInt32("max-height", &height)) { + width = max(width, (int32_t)def.format.video.nFrameWidth); + height = max(height, (int32_t)def.format.video.nFrameHeight); + ALOGV("Adaptive playback width = %d, height = %d", width, height); + } else { + width = def.format.video.nFrameWidth; + height = def.format.video.nFrameHeight; + } err = setNativeWindowSizeFormatAndUsage( nativeWindow, - def.format.video.nFrameWidth, - def.format.video.nFrameHeight, + width, + height, def.format.video.eColorFormat, mRotationDegrees, usage); From 0ecb6683f99e3fca6ff94ad2341656464e17990d Mon Sep 17 00:00:00 2001 From: Li Sun Date: Wed, 9 Dec 2015 18:28:10 +0530 Subject: [PATCH 29/32] Nuplayer: Flush the decoder if seamless format change is supported In smooth streaming enabled case, flush the decoder if seamless format change is supported. Otherwise, ramdomly video frames with old resolution are queued to the new surface and results in green frames. Calling flush ensures that all the old video frames are cleared. Change-Id: Ia020a01fd0eaa8af8e48b6edb526a3f53875b068 --- .../nuplayer/NuPlayer.cpp | 15 ++++++++++-- .../nuplayer/NuPlayerDecoder.cpp | 23 ++++++++++++++++--- .../nuplayer/NuPlayerDecoder.h | 1 + 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 09909b5f733..a0446ffbb2b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -953,10 +953,21 @@ void NuPlayer::onMessageReceived(const sp &msg) { audio ? "audio" : "video", formatChange); if (formatChange) { - mDeferredActions.push_back( - new FlushDecoderAction( + int32_t seamlessChange = 0; + if (msg->findInt32("video-seamlessChange", &seamlessChange) && seamlessChange) { + ALOGE("video decoder seamlessChange in smooth streaming mode, " + "flush the video decoder"); + mDeferredActions.push_back( + new FlushDecoderAction(FLUSH_CMD_NONE, FLUSH_CMD_FLUSH)); + mDeferredActions.push_back(new ResumeDecoderAction(false)); + processDeferredActions(); + break; + } else { + mDeferredActions.push_back( + new FlushDecoderAction( audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN)); + } } mDeferredActions.push_back( diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 282686fb281..2f8585ba809 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -93,6 +93,7 @@ NuPlayer::Decoder::Decoder( mIsSecure(false), mFormatChangePending(false), mTimeChangePending(false), + mVideoFormatChangeDoFlushOnly(false), mResumePending(false), mComponentName("decoder") { mCodecLooper = new ALooper; @@ -263,6 +264,7 @@ void NuPlayer::Decoder::onConfigure(const sp &format) { mFormatChangePending = false; mTimeChangePending = false; + mVideoFormatChangeDoFlushOnly = false; ++mBufferGeneration; @@ -773,9 +775,20 @@ status_t NuPlayer::Decoder::fetchInputData(sp &reply) { mTimeChangePending = true; err = ERROR_END_OF_STREAM; } else if (seamlessFormatChange) { - // reuse existing decoder and don't flush - rememberCodecSpecificData(newFormat); - continue; + if (!mIsAudio && + newFormat != NULL && + newFormat->contains("prefer-adaptive-playback")) { + ALOGV("in smooth streaming mode, " + "do video flush in video seamless format change"); + mFormatChangePending = true; + mVideoFormatChangeDoFlushOnly = true; + err = ERROR_END_OF_STREAM; + } else { + // reuse existing decoder and don't flush + rememberCodecSpecificData(newFormat); + continue; + } + } else { // This stream is unaffected by the discontinuity return -EWOULDBLOCK; @@ -1003,10 +1016,14 @@ void NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { sp msg = mNotify->dup(); msg->setInt32("what", kWhatInputDiscontinuity); msg->setInt32("formatChange", mFormatChangePending); + if (mVideoFormatChangeDoFlushOnly) { + msg->setInt32("video-seamlessChange", mVideoFormatChangeDoFlushOnly); + } msg->post(); mFormatChangePending = false; mTimeChangePending = false; + mVideoFormatChangeDoFlushOnly = false; } bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index ba25041c4e3..a179c873181 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -109,6 +109,7 @@ struct NuPlayer::Decoder : public DecoderBase { bool mIsSecure; bool mFormatChangePending; bool mTimeChangePending; + bool mVideoFormatChangeDoFlushOnly; bool mResumePending; AString mComponentName; From 5e141397b48e9f158848422599caee024e35ad6b Mon Sep 17 00:00:00 2001 From: Surajit Podder Date: Wed, 13 Jan 2016 12:42:43 +0530 Subject: [PATCH 30/32] video: Add support to push blank buffers on surface switch Add support to push blank buffers only on surface switch. Setting "push-blank-buffers-on-switch" key with value 1 will enable this feature. Change-Id: I4a0fc48fe24c09a6b8d0e2e0fc4dc2e96d3178bf --- include/media/stagefright/ACodec.h | 1 + media/libstagefright/ACodec.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index ebfdc7b47c7..74885a9a6f2 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -165,6 +165,7 @@ struct ACodec : public AHierarchicalStateMachine, public CodecBase { kFlagIsSecure = 1, kFlagPushBlankBuffersToNativeWindowOnShutdown = 2, kFlagIsGrallocUsageProtected = 4, + kFlagPushBlankBuffersToNativeWindowOnSwitch = 1 << 7, }; enum { diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 82a1fa64d47..394c5dec622 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -803,7 +803,8 @@ status_t ACodec::handleSetSurface(const sp &surface) { } // push blank buffers to previous window if requested - if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) { + if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown || + mFlags & kFlagPushBlankBuffersToNativeWindowOnSwitch) { pushBlankBuffersToNativeWindow(mNativeWindow.get()); } @@ -1982,6 +1983,12 @@ status_t ACodec::configureCodec( && push != 0) { mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; } + + int32_t val; + if (msg->findInt32("push-blank-buffers-on-switch", &val) + && val != 0) { + mFlags |= kFlagPushBlankBuffersToNativeWindowOnSwitch; + } } int32_t rotationDegrees; From b62239bc933448d0a717a945ef1bfc0b2a84675e Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Fri, 20 Nov 2015 10:34:35 -0800 Subject: [PATCH 31/32] libstagefright: check requested memory size before allocation for SoftMPEG4Encoder and SoftVPXEncoder Bug: 25812794 Change-Id: I96dc74734380d462583f6efa33d09946f9532809 (cherry picked from commit 87f8cbb223ee516803dbb99699320c2484cbf3ba) (cherry picked from commit 69bd1cf225328e64a5b4ae6935d2b7fe0b7b6400) --- .../codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp | 9 +++++++++ media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index 8240f831b05..f2a4e65f2d6 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -37,6 +37,10 @@ #include +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif + namespace android { template @@ -137,6 +141,11 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { // Color conversion is needed. free(mInputFrameData); + mInputFrameData = NULL; + if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { + ALOGE("b/25812794, Buffer size is too big."); + return OMX_ErrorBadParameter; + } mInputFrameData = (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); CHECK(mInputFrameData != NULL); diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index e65484325eb..410f9d0d940 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -26,6 +26,10 @@ #include #include +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif + namespace android { template @@ -315,6 +319,11 @@ status_t SoftVPXEncoder::initEncoder() { if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { free(mConversionBuffer); + mConversionBuffer = NULL; + if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { + ALOGE("b/25812794, Buffer size is too big."); + return UNKNOWN_ERROR; + } mConversionBuffer = (uint8_t *)malloc(mWidth * mHeight * 3 / 2); if (mConversionBuffer == NULL) { ALOGE("Allocating conversion buffer failed."); From e65d1ede2887bb3f718271765b2b9664e1c02b85 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Fri, 4 Dec 2015 16:29:16 -0800 Subject: [PATCH 32/32] Fix security vulnerability in ICrypto DO NOT MERGE. b/25800375 Change-Id: I03c9395f7c7de4ac5813a1207452aac57aa39484 (cherry picked from commit 22f824feac43d5758f9a70b77f2aca840ba62c3b) --- media/libmedia/ICrypto.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp index 24e027e1167..e759187987a 100644 --- a/media/libmedia/ICrypto.cpp +++ b/media/libmedia/ICrypto.cpp @@ -326,7 +326,9 @@ status_t BnCrypto::onTransact( if (overflow || sumSubsampleSizes != totalSize) { result = -EINVAL; - } else if (offset + totalSize > sharedBuffer->size()) { + } else if (totalSize > sharedBuffer->size()) { + result = -EINVAL; + } else if ((size_t)offset > sharedBuffer->size() - totalSize) { result = -EINVAL; } else { result = decrypt(