Merge "Move test to "presubmit" group, it's already included like this in another location"
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 94cf743..ba20b95 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -37,6 +37,7 @@
#include <ctime>
#include <deque>
#include <endian.h>
+#include <inttypes.h>
#include <iterator>
#include <mutex>
#include <string>
@@ -105,9 +106,9 @@
void LogToBuffer(android_LogPriority level, const uint8_t uuid[16], const char *fmt, Args... args) {
uint64_t uuid2[2] = {};
std::memcpy(uuid2, uuid, sizeof(uuid2));
- std::string uuidFmt("uuid=[%lx %lx] ");
+ std::string uuidFmt("uuid=[%" PRIx64 " %" PRIx64 "] ");
uuidFmt += fmt;
- LogToBuffer(level, uuidFmt.c_str(), htobe64(uuid2[0]), htobe64(uuid2[1]), args...);
+ LogToBuffer(level, uuidFmt.c_str(), betoh64(uuid2[0]), betoh64(uuid2[1]), args...);
}
#ifndef LOG2BE
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
index c510fca..6bcad4a 100644
--- a/media/codec2/vndk/internal/C2BlockInternal.h
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -238,7 +238,7 @@
* - Local migration on blockpool side will be done automatically by
* blockpool.
* - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called
- * to test eligiblity.
+ * to test eligibility.
* - After attachBuffer() is called, EndAttachBlockToBufferQueue() should
* be called. This will set "held" status to true. If it returned
* false, cancelBuffer() should be called.
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 3f19219..aea31a0 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -256,6 +256,7 @@
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
"effectsAidlConversion/AidlConversionAec.cpp",
+ "effectsAidlConversion/AidlConversionAgc1.cpp",
"effectsAidlConversion/AidlConversionAgc2.cpp",
"effectsAidlConversion/AidlConversionBassBoost.cpp",
"effectsAidlConversion/AidlConversionDownmix.cpp",
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index dcc9127..e4a26b1 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -36,6 +36,7 @@
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Flags;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::aidl::android::media::audio::common::AudioMode;
@@ -67,7 +68,11 @@
EffectConversionHelperAidl::EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
int32_t sessionId, int32_t ioId, const Descriptor& desc)
- : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
+ : mSessionId(sessionId),
+ mIoId(ioId),
+ mDesc(desc),
+ mEffect(std::move(effect)),
+ mIsInputStream(mDesc.common.flags.type == Flags::Type::PRE_PROC) {
mCommon.session = sessionId;
mCommon.ioHandle = ioId;
mCommon.input = mCommon.output = kDefaultAudioConfig;
@@ -139,16 +144,32 @@
return ret;
}
-status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize,
- const void* pCmdData __unused,
+status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
if (!replySize || *replySize != sizeof(int) || !pReplyData ||
cmdSize != sizeof(effect_config_t)) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
return BAD_VALUE;
}
- // TODO: need to implement setConfig with setParameter(common)
- return *static_cast<int32_t*>(pReplyData) = OK;
+ effect_config_t* config = (effect_config_t*)pCmdData;
+ Parameter::Common aidlCommon = {
+ .session = mSessionId,
+ .ioHandle = mIoId,
+ .input = {.base = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ config->inputCfg, mIsInputStream))},
+ .output = {.base = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ config->outputCfg, mIsInputStream))}};
+
+ Parameter aidlParam = UNION_MAKE(Parameter, common, aidlCommon);
+
+ status_t ret = statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+ EffectParamWriter writer(*(effect_param_t*)pReplyData);
+ writer.setStatus(ret);
+ return ret;
}
status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 0494190..54df1b8 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -40,6 +40,8 @@
const int32_t mIoId;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+ // whether the effect is instantiated on an input stream
+ const bool mIsInputStream;
::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index a684dee..3e843c6 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -35,6 +35,7 @@
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include "effectsAidlConversion/AidlConversionAec.h"
+#include "effectsAidlConversion/AidlConversionAgc1.h"
#include "effectsAidlConversion/AidlConversionAgc2.h"
#include "effectsAidlConversion/AidlConversionBassBoost.h"
#include "effectsAidlConversion/AidlConversionDownmix.h"
@@ -89,6 +90,9 @@
if (typeUuid == kAcousticEchoCancelerTypeUUID) {
mConversion =
std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId, desc);
+ } else if (typeUuid == kAutomaticGainControl1TypeUUID) {
+ mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
+ desc);
} else if (typeUuid == kAutomaticGainControl2TypeUUID) {
mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
desc);
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
new file mode 100644
index 0000000..0ca5568
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#include <cstdint>
+#include <cstring>
+#include <optional>
+#define LOG_TAG "AidlConversionAgc1"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionEffect.h>
+#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/effect_agc.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionAgc1.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControlV1;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::getParameterSpecificField;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionAgc1::setParameterLevel(EffectParamReader& param) {
+ int16_t level;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&level));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ targetPeakLevelDbFs, level);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameterGain(EffectParamReader& param) {
+ int16_t gain;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&gain));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ maxCompressionGainDb, gain);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameterLimiterEnable(EffectParamReader& param) {
+ bool enable;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&enable));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ enableLimiter, enable);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ switch (type) {
+ case AGC_PARAM_TARGET_LEVEL: {
+ return setParameterLevel(param);
+ }
+ case AGC_PARAM_COMP_GAIN: {
+ return setParameterGain(param);
+ }
+ case AGC_PARAM_LIMITER_ENA: {
+ return setParameterLimiterEnable(param);
+ }
+ case AGC_PARAM_PROPERTIES: {
+ RETURN_STATUS_IF_ERROR(setParameterLevel(param));
+ RETURN_STATUS_IF_ERROR(setParameterGain(param));
+ RETURN_STATUS_IF_ERROR(setParameterLimiterEnable(param));
+ return OK;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+}
+
+status_t AidlConversionAgc1::getParameterLevel(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::targetPeakLevelDbFs);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int32_t level = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::targetPeakLevelDbFs, int32_t));
+ return param.writeToValue(&level);
+}
+
+status_t AidlConversionAgc1::getParameterGain(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::maxCompressionGainDb);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int32_t gain = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::maxCompressionGainDb, int32_t));
+ return param.writeToValue(&gain);
+}
+
+status_t AidlConversionAgc1::getParameterLimiterEnable(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::enableLimiter);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ bool enable = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::enableLimiter, bool));
+ return param.writeToValue(&enable);
+}
+
+status_t AidlConversionAgc1::getParameter(EffectParamWriter& param) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ switch (type) {
+ case AGC_PARAM_TARGET_LEVEL: {
+ return getParameterLevel(param);
+ }
+ case AGC_PARAM_COMP_GAIN: {
+ return getParameterGain(param);
+ }
+ case AGC_PARAM_LIMITER_ENA: {
+ return getParameterLimiterEnable(param);
+ }
+ case AGC_PARAM_PROPERTIES: {
+ RETURN_STATUS_IF_ERROR(getParameterLevel(param));
+ RETURN_STATUS_IF_ERROR(getParameterGain(param));
+ RETURN_STATUS_IF_ERROR(getParameterLimiterEnable(param));
+ return OK;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
new file mode 100644
index 0000000..b0509fd
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+class AidlConversionAgc1 : public EffectConversionHelperAidl {
+ public:
+ AidlConversionAgc1(std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc) {}
+ ~AidlConversionAgc1() {}
+
+ private:
+ status_t setParameterLevel(utils::EffectParamReader& param);
+ status_t setParameterGain(utils::EffectParamReader& param);
+ status_t setParameterLimiterEnable(utils::EffectParamReader& param);
+ status_t setParameter(utils::EffectParamReader& param) override;
+
+ status_t getParameterLevel(utils::EffectParamWriter& param);
+ status_t getParameterGain(utils::EffectParamWriter& param);
+ status_t getParameterLimiterEnable(utils::EffectParamWriter& param);
+ status_t getParameter(utils::EffectParamWriter& param) override;
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
index 4555c9f..325739c 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
@@ -27,7 +27,7 @@
#include <media/audiohal/AudioEffectUuid.h>
#include <system/audio_effect.h>
#include <system/audio_effects/effect_dynamicsprocessing.h>
-
+#include <Utils.h>
#include <utils/Log.h>
#include "AidlConversionDynamicsProcessing.h"
@@ -47,19 +47,13 @@
status_t AidlConversionDp::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- if (OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&type));
Parameter aidlParam;
switch (type) {
case DP_PARAM_INPUT_GAIN: {
DynamicsProcessing::InputGain inputGainAidl;
- if (OK != param.readFromParameter(&inputGainAidl.channel) ||
- OK != param.readFromValue(&inputGainAidl.gainDb)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&inputGainAidl.channel));
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&inputGainAidl.gainDb));
aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, inputGain,
{inputGainAidl});
break;
@@ -132,17 +126,12 @@
status_t AidlConversionDp::getParameter(EffectParamWriter& param) {
uint32_t type = 0;
- if (OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&type));
Parameter aidlParam;
switch (type) {
case DP_PARAM_INPUT_GAIN: {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::inputGain);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
@@ -161,11 +150,6 @@
return BAD_VALUE;
}
case DP_PARAM_ENGINE_ARCHITECTURE: {
- int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::engineArchitecture);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
@@ -186,18 +170,15 @@
VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.postEqStage.inUse));
int32_t limiterInUse =
VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.limiterInUse));
- if (OK != param.writeToValue(&resolution) ||
- OK != param.writeToValue(&engine.preferredProcessingDurationMs) ||
- OK != param.writeToValue(&preEqInUse) ||
- OK != param.writeToValue(&engine.preEqStage.bandCount) ||
- OK != param.writeToValue(&mbcInUse) ||
- OK != param.writeToValue(&engine.mbcStage.bandCount) ||
- OK != param.writeToValue(&postEqInUse) ||
- OK != param.writeToValue(&engine.postEqStage.bandCount) ||
- OK != param.writeToValue(&limiterInUse)) {
- ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&resolution));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.preferredProcessingDurationMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&preEqInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.preEqStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&mbcInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.mbcStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&postEqInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.postEqStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&limiterInUse));
mEngine = engine;
return OK;
}
@@ -223,14 +204,9 @@
return getLimiterConfig(param);
}
case DP_PARAM_GET_CHANNEL_COUNT: {
- uint32_t channel = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- mCommon.input.base.channelMask, true /* input */));
- if (OK != param.writeToValue(&channel)) {
- ALOGE("%s write channel number %d to param failed %s", __func__, channel,
- param.toString().c_str());
- return BAD_VALUE;
- }
+ uint32_t channel = ::android::hardware::audio::common::getChannelCount(
+ mCommon.input.base.channelMask);
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&channel));
return OK;
}
default: {
@@ -243,10 +219,9 @@
aidl::ConversionResult<DynamicsProcessing::ChannelConfig>
AidlConversionDp::readChannelConfigFromParam(EffectParamReader& param) {
int32_t enable, channel;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromValue(&enable)) {
- ALOGE("%s invalid channel config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+
return DynamicsProcessing::ChannelConfig(
{.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable)), .channel = channel});
}
@@ -255,14 +230,12 @@
AidlConversionDp::readEqBandConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::EqBandConfig config;
int32_t enable;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromParameter(&config.band) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.cutoffFrequencyHz) ||
- OK != param.readFromValue(&config.gainDb)) {
- ALOGE("%s invalid eq band param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromParameter(&config.band));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.cutoffFrequencyHz));
+ RETURN_IF_ERROR(param.readFromValue(&config.gainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -271,22 +244,20 @@
AidlConversionDp::readMbcBandConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::MbcBandConfig config;
int32_t enable;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromParameter(&config.band) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.cutoffFrequencyHz) ||
- OK != param.readFromValue(&config.attackTimeMs) ||
- OK != param.readFromValue(&config.releaseTimeMs) ||
- OK != param.readFromValue(&config.ratio) ||
- OK != param.readFromValue(&config.thresholdDb) ||
- OK != param.readFromValue(&config.kneeWidthDb) ||
- OK != param.readFromValue(&config.noiseGateThresholdDb) ||
- OK != param.readFromValue(&config.expanderRatio) ||
- OK != param.readFromValue(&config.preGainDb) ||
- OK != param.readFromValue(&config.postGainDb)) {
- ALOGE("%s invalid mbc band config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromParameter(&config.band));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.cutoffFrequencyHz));
+ RETURN_IF_ERROR(param.readFromValue(&config.attackTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.releaseTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.ratio));
+ RETURN_IF_ERROR(param.readFromValue(&config.thresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.kneeWidthDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.noiseGateThresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.expanderRatio));
+ RETURN_IF_ERROR(param.readFromValue(&config.preGainDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.postGainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -295,18 +266,16 @@
AidlConversionDp::readLimiterConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::LimiterConfig config;
int32_t enable, inUse;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromValue(&inUse) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.linkGroup) ||
- OK != param.readFromValue(&config.attackTimeMs) ||
- OK != param.readFromValue(&config.releaseTimeMs) ||
- OK != param.readFromValue(&config.ratio) ||
- OK != param.readFromValue(&config.thresholdDb) ||
- OK != param.readFromValue(&config.postGainDb)) {
- ALOGE("%s invalid limiter config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromValue(&inUse));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.linkGroup));
+ RETURN_IF_ERROR(param.readFromValue(&config.attackTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.releaseTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.ratio));
+ RETURN_IF_ERROR(param.readFromValue(&config.thresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.postGainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -315,18 +284,15 @@
AidlConversionDp::readEngineArchitectureFromParam(EffectParamReader& param) {
DynamicsProcessing::EngineArchitecture engine;
int32_t variant, preEqInUse, mbcInUse, postEqInUse, limiterInUse;
- if (OK != param.readFromValue(&variant) &&
- OK != param.readFromValue(&engine.preferredProcessingDurationMs) &&
- OK != param.readFromValue(&preEqInUse) &&
- OK != param.readFromValue(&engine.preEqStage.bandCount) &&
- OK != param.readFromValue(&mbcInUse) &&
- OK != param.readFromValue(&engine.mbcStage.bandCount) &&
- OK != param.readFromValue(&postEqInUse) &&
- OK != param.readFromValue(&engine.postEqStage.bandCount) &&
- OK != param.readFromValue(&limiterInUse)) {
- ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromValue(&variant));
+ RETURN_IF_ERROR(param.readFromValue(&engine.preferredProcessingDurationMs));
+ RETURN_IF_ERROR(param.readFromValue(&preEqInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.preEqStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&mbcInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.mbcStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&postEqInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.postEqStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&limiterInUse));
engine.resolutionPreference = VALUE_OR_RETURN(
aidl::android::legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(variant));
@@ -339,10 +305,7 @@
status_t AidlConversionDp::getChannelConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
@@ -384,13 +347,9 @@
for (const auto& ch : channels) {
if (ch.channel == channel) {
int32_t enable = ch.enable;
- if (OK != param.writeToValue(&inUse) ||
- OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandCount)) {
- ALOGE("%s failed to write into param value %s", __func__,
- param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&inUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandCount));
return OK;
}
}
@@ -400,10 +359,8 @@
status_t AidlConversionDp::getEqBandConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
int32_t channel, band;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&band));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
@@ -425,12 +382,9 @@
for (const auto& bandIt : bands) {
if (bandIt.channel == channel && bandIt.band == band) {
int32_t enable = bandIt.enable;
- if (OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
- OK != param.writeToValue(&bandIt.gainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.cutoffFrequencyHz));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.gainDb));
return OK;
}
}
@@ -440,10 +394,8 @@
status_t AidlConversionDp::getMbcBandConfig(EffectParamWriter& param) {
int32_t channel, band;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&band));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::mbcBand);
@@ -457,20 +409,17 @@
for (const auto& bandIt : bands) {
if (bandIt.channel == channel && bandIt.band == band) {
int32_t enable = bandIt.enable;
- if (OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
- OK != param.writeToValue(&bandIt.attackTimeMs) ||
- OK != param.writeToValue(&bandIt.releaseTimeMs) ||
- OK != param.writeToValue(&bandIt.ratio) ||
- OK != param.writeToValue(&bandIt.thresholdDb) ||
- OK != param.writeToValue(&bandIt.kneeWidthDb) ||
- OK != param.writeToValue(&bandIt.noiseGateThresholdDb) ||
- OK != param.writeToValue(&bandIt.expanderRatio) ||
- OK != param.writeToValue(&bandIt.preGainDb) ||
- OK != param.writeToValue(&bandIt.postGainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.cutoffFrequencyHz));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.attackTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.releaseTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.ratio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.thresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.kneeWidthDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.noiseGateThresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.expanderRatio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.preGainDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.postGainDb));
return OK;
}
}
@@ -480,10 +429,7 @@
status_t AidlConversionDp::getLimiterConfig(EffectParamWriter& param) {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::limiter);
@@ -498,17 +444,14 @@
if (config.channel == channel) {
int32_t inUse = mEngine.limiterInUse;
int32_t enable = config.enable;
- if (OK != param.writeToValue(&inUse) ||
- OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&config.linkGroup) ||
- OK != param.writeToValue(&config.attackTimeMs) ||
- OK != param.writeToValue(&config.releaseTimeMs) ||
- OK != param.writeToValue(&config.ratio) ||
- OK != param.writeToValue(&config.thresholdDb) ||
- OK != param.writeToValue(&config.postGainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&inUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.linkGroup));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.attackTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.releaseTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.ratio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.thresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.postGainDb));
return OK;
}
}
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
index 3b8076f..5d491a4 100644
--- a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -29,6 +29,12 @@
0x11e0,
0xbd61,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// ae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControl1TypeUUID = {static_cast<int32_t>(0xae3c653b),
+ 0xbe18,
+ 0x4ab8,
+ 0x8938,
+ {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
static const AudioUuid kAutomaticGainControl2TypeUUID = {static_cast<int32_t>(0xae3c653b),
0xbe18,
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index a8843d6..c076ccc 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -27,6 +27,7 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <system/audio_effects/audio_effects_utils.h>
#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_agc.h>
#include <system/audio_effects/effect_agc2.h>
#include <system/audio_effects/effect_bassboost.h>
#include <system/audio_effects/effect_downmix.h>
@@ -157,6 +158,9 @@
std::make_tuple(FX_IID_AEC,
createEffectParamCombination(AEC_PARAM_ECHO_DELAY, 0xff /* echoDelayMs */,
sizeof(int32_t) /* returnValueSize */)),
+ std::make_tuple(FX_IID_AGC,
+ createEffectParamCombination(AGC_PARAM_TARGET_LEVEL, 20 /* targetLevel */,
+ sizeof(int16_t) /* returnValueSize */)),
std::make_tuple(FX_IID_AGC2, createEffectParamCombination(
AGC2_PARAM_FIXED_DIGITAL_GAIN, 15 /* digitalGainDb */,
sizeof(int32_t) /* returnValueSize */)),
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
index 7978cc5..7f21f5d 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -64,6 +64,7 @@
RetCode DynamicsProcessingContext::setCommon(const Parameter::Common& common) {
mCommon = common;
init();
+ LOG(INFO) << __func__ << common.toString();
return RetCode::SUCCESS;
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index c5b5199..863177d 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -798,6 +798,8 @@
{ "dvb-audio-description", kKeyDvbAudioDescription},
{ "dvb-teletext-magazine-number", kKeyDvbTeletextMagazineNumber},
{ "dvb-teletext-page-number", kKeyDvbTeletextPageNumber},
+ { "profile", kKeyAudioProfile },
+ { "level", kKeyAudioLevel },
}
};
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 33f224c..80a1170 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -117,6 +117,12 @@
kKeyVideoProfile = 'vprf', // int32_t
kKeyVideoLevel = 'vlev', // int32_t
+ // audio profile and level
+ // The codec framework doesn't distinguish between video and audio profiles,
+ // so there is no need to define a separate key
+ kKeyAudioProfile = 'vprf', // int32_t
+ kKeyAudioLevel = 'vlev', // int32_t
+
kKey2ByteNalLength = '2NAL', // int32_t (bool)
// Identify the file output format for authoring
diff --git a/media/module/foundation/MediaDefs.cpp b/media/module/foundation/MediaDefs.cpp
index 4a75f90..7abab63 100644
--- a/media/module/foundation/MediaDefs.cpp
+++ b/media/module/foundation/MediaDefs.cpp
@@ -72,6 +72,7 @@
const char *MEDIA_MIMETYPE_AUDIO_DTS = "audio/vnd.dts";
const char *MEDIA_MIMETYPE_AUDIO_DTS_HD = "audio/vnd.dts.hd";
const char *MEDIA_MIMETYPE_AUDIO_DTS_HD_MA = "audio/vnd.dts.hd;profile=dtsma";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd";
const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1 = "audio/vnd.dts.uhd;profile=p1";
const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2 = "audio/vnd.dts.uhd;profile=p2";
const char *MEDIA_MIMETYPE_AUDIO_EVRC = "audio/evrc";
diff --git a/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
index 740336a..05ee7fc 100644
--- a/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
+++ b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
@@ -74,6 +74,7 @@
extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD_MA;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2;
extern const char *MEDIA_MIMETYPE_AUDIO_EVRC;
diff --git a/media/module/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
index 1482072..6aeea3b 100644
--- a/media/module/mpeg2ts/ATSParser.cpp
+++ b/media/module/mpeg2ts/ATSParser.cpp
@@ -556,7 +556,15 @@
if (descriptor_length > ES_info_length) {
return ERROR_MALFORMED;
}
- if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
+
+ // The DTS descriptor is used in the PSI PMT to identify streams which carry
+ // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
+ // descriptors shall not be present in the same ES_info descriptor loop.
+ if (descriptor_tag == DESCRIPTOR_DTS) {
+ info.mType = STREAMTYPE_DTS;
+ ES_info_length -= descriptor_length;
+ br->skipBits(descriptor_length * 8);
+ } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
hasStreamCA = true;
streamCA.mSystemID = br->getBits(16);
streamCA.mPID = br->getBits(16) & 0x1fff;
@@ -575,6 +583,16 @@
if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
br->skipBits(descriptor_length * 8);
+ } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
+ // DTS HD extended descriptor which can accommodate core only formats
+ // as well as extension only and core + extension combinations.
+ info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
+ br->skipBits(descriptor_length * 8);
+ } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
+ // The DTS-UHD descriptor is used in the PSI PMT to identify streams
+ // which carry DTS-UHD audio
+ info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
+ br->skipBits(descriptor_length * 8);
} else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
descriptor_length >= 1) {
// DVB BlueBook A038 Table 110
@@ -920,9 +938,17 @@
mode = ElementaryStreamQueue::EAC3;
break;
+ case STREAMTYPE_DTS:
+ mode = ElementaryStreamQueue::DTS;
+ break;
+
case STREAMTYPE_PES_PRIVATE_DATA:
if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
mode = ElementaryStreamQueue::AC4;
+ } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
+ mode = ElementaryStreamQueue::DTS_HD;
+ } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
+ mode = ElementaryStreamQueue::DTS_UHD;
}
break;
@@ -1158,9 +1184,12 @@
case STREAMTYPE_EAC3:
case STREAMTYPE_AAC_ENCRYPTED:
case STREAMTYPE_AC3_ENCRYPTED:
+ case STREAMTYPE_DTS:
return true;
case STREAMTYPE_PES_PRIVATE_DATA:
- return mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4;
+ return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
+ || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
+ || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);
default:
return false;
diff --git a/media/module/mpeg2ts/ESQueue.cpp b/media/module/mpeg2ts/ESQueue.cpp
index 192ba77..2dc7b0a 100644
--- a/media/module/mpeg2ts/ESQueue.cpp
+++ b/media/module/mpeg2ts/ESQueue.cpp
@@ -362,6 +362,436 @@
return OK;
}
+#define RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitstream, size) \
+ do { \
+ if ((bitstream).numBitsLeft() < (size)) { \
+ ALOGE("Not enough bits left for further parsing"); \
+ return ERROR_MALFORMED; } \
+ } while (0)
+
+// Parse DTS Digital Surround and DTS Express(LBR) stream header
+static status_t parseDTSHDSyncFrame(
+ const uint8_t *ptr, size_t size, unsigned &frameSize, sp<MetaData> *metaData) {
+ static const unsigned channelCountTable[] = {1, 2, 2, 2, 2, 3, 3, 4,
+ 4, 5, 6, 6, 6, 7, 8, 8};
+ static const unsigned samplingRateTableCoreSS[] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050,
+ 44100, 0, 0, 12000, 24000, 48000, 0, 0};
+ static const unsigned samplingRateTableExtSS[] = {8000, 16000, 32000, 64000, 128000,
+ 22050, 44100, 88200, 176400, 352800,
+ 12000, 24000, 48000, 96000, 192000, 384000};
+
+ const uint32_t DTSHD_SYNC_CORE_16BIT_BE = 0x7ffe8001;
+ const uint32_t DTSHD_SYNC_EXSS_16BIT_BE = 0x64582025;
+
+ uint32_t numChannels = 0, samplingRate = 0;
+ bool isLBR = false;
+
+ ABitReader bits(ptr, size);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 32);
+ uint32_t dtshdSyncWord = bits.getBits(32);
+
+ // Expecting DTS Digital Surround or DTS Express(LBR) streams only
+ if (dtshdSyncWord == DTSHD_SYNC_CORE_16BIT_BE) { // DTS Digital Surround Header
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1 + 5 + 1 + 7 + 14 + 6 + 4 + 15 + 2));
+
+ // FTYPE, SHORT, CRC, NBLKS
+ bits.skipBits(1 + 5 + 1 + 7);
+
+ frameSize = bits.getBits(14) + 1;
+ uint32_t amode = bits.getBits(6);
+ uint32_t freqIndex = bits.getBits(4);
+
+ // RATE, FIXEDBIT, DYNF, TIMEF, AUXF, HDCD, EXT_AUDIO_ID, EXT_AUDIO, ASPF
+ bits.skipBits(5 + 1 + 1 + 1 + 1 + 1 + 3 + 1 + 1);
+
+ uint32_t lfeFlag = bits.getBits(2);
+ numChannels = (amode <= 15) ? channelCountTable[amode] : 0;
+ numChannels += ((lfeFlag == 1) || (lfeFlag == 2)) ? 1 : 0;
+ samplingRate = (freqIndex <= 15) ? samplingRateTableCoreSS[freqIndex] : 0;
+
+ isLBR = false;
+ } else if (dtshdSyncWord == DTSHD_SYNC_EXSS_16BIT_BE) { // DTS Express(LBR) Header
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (8 + 2 + 1));
+
+ uint32_t extHeadersize, extSSFsize;
+ uint32_t numAudioPresent = 1, numAssets = 1;
+ uint32_t nuActiveExSSMask[8];
+
+ // userDefinedBits
+ bits.skipBits(8);
+
+ uint32_t extSSIndex = bits.getBits(2);
+ uint32_t headerSizeType = bits.getBits(1);
+
+ if (headerSizeType == 0) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (8 + 16));
+
+ extHeadersize = bits.getBits(8) + 1;
+ extSSFsize = bits.getBits(16) + 1;
+ } else {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (12 + 20));
+
+ extHeadersize = bits.getBits(12) + 1;
+ extSSFsize = bits.getBits(20) + 1;
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1));
+
+ uint32_t staticFieldsPresent = bits.getBits(1);
+
+ if (staticFieldsPresent) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (2 + 3 + 1));
+
+ // nuRefClockCode, nuExSSFrameDurationCode
+ bits.skipBits(2 + 3);
+
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (32 + 4));
+
+ bits.skipBits(32 + 4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (3 + 3));
+
+ // numAudioPresent, numAssets
+ bits.skipBits(3 + 3);
+
+ for (uint32_t nAuPr = 0; nAuPr < numAudioPresent; nAuPr++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (extSSIndex + 1));
+
+ nuActiveExSSMask[nAuPr] = bits.getBits(extSSIndex + 1);
+ }
+
+ for (uint32_t nAuPr = 0; nAuPr < numAudioPresent; nAuPr++) {
+ for (uint32_t nSS = 0; nSS < extSSIndex + 1; nSS++) {
+ if (((nuActiveExSSMask[nAuPr] >> nSS) & 0x1) == 1) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 8);
+
+ // nuActiveAssetMask
+ bits.skipBits(8);
+ }
+ }
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bMixMetadataEnbl
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (2 + 2 + 2));
+
+ // nuMixMetadataAdjLevel
+ bits.skipBits(2);
+
+ uint32_t bits4MixOutMask = (bits.getBits(2) + 1) << 2;
+ uint32_t numMixOutConfigs = bits.getBits(2) + 1;
+
+ for (int ns = 0; ns < numMixOutConfigs; ns++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, bits4MixOutMask);
+
+ // nuMixOutChMask
+ bits.skipBits(bits4MixOutMask);
+ }
+ }
+ }
+
+ for (int nAst = 0; nAst < numAssets; nAst++) {
+ int bits4ExSSFsize = (headerSizeType == 0) ? 16 : 20;
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, bits4ExSSFsize);
+
+ bits.skipBits(bits4ExSSFsize);
+ }
+
+ /* Asset descriptor */
+ for (int nAst = 0; nAst < numAssets; nAst++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (9 + 3));
+
+ // nuAssetDescriptFsize, nuAssetIndex
+ bits.skipBits(9 + 3);
+
+ if (staticFieldsPresent) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bAssetTypeDescrPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 4);
+
+ // nuAssetTypeDescriptor
+ bits.skipBits(4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bLanguageDescrPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 24);
+
+ // LanguageDescriptor
+ bits.skipBits(24);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bInfoTextPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 10);
+
+ uint32_t nuInfoTextByteSize = bits.getBits(10) + 1;
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (nuInfoTextByteSize * 8));
+
+ // InfoTextString
+ bits.skipBits(nuInfoTextByteSize * 8);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (5 + 4 + 8));
+
+ // nuBitResolution
+ bits.skipBits(5);
+
+ samplingRate = samplingRateTableExtSS[bits.getBits(4)];
+ numChannels = bits.getBits(8) + 1;
+ }
+ }
+
+ frameSize = extHeadersize + extSSFsize;
+ isLBR = true;
+ } else {
+ ALOGE("No valid sync word in DTS/DTSHD header");
+ return ERROR_MALFORMED;
+ }
+
+ if (metaData != NULL) {
+ if (isLBR) {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS_HD);
+ (*metaData)->setInt32(kKeyAudioProfile, 0x2); // CodecProfileLevel.DTS_HDProfileLBR
+ } else {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS);
+ }
+ (*metaData)->setInt32(kKeyChannelCount, numChannels);
+ (*metaData)->setInt32(kKeySampleRate, samplingRate);
+ }
+ return OK;
+}
+
+static status_t extractVarLenBitFields(
+ ABitReader *bits, size_t *bitsUsed, uint32_t *value,
+ unsigned ucTable[], bool extractAndAddFlag) {
+
+ static const unsigned bitsUsedTbl[8] = {1, 1, 1, 1, 2, 2, 3, 3}; // prefix code lengths
+ static const unsigned indexTbl[8] = {0, 0, 0, 0, 1, 1, 2, 3}; // code to prefix code index map
+
+ /* Clone the bitstream */
+ ABitReader bitStream(bits->data(), bits->numBitsLeft() / 8);
+ ABitReader bitstreamClone(bits->data(), bits->numBitsLeft() / 8);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitstreamClone, 3);
+
+ unsigned code = bitstreamClone.getBits(3);
+ unsigned totalBitsUsed = bitsUsedTbl[code];
+ unsigned unIndex = indexTbl[code];
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, totalBitsUsed);
+
+ bitStream.skipBits(totalBitsUsed);
+
+ uint32_t unValue = 0;
+ if (ucTable[unIndex] > 0) {
+ if (extractAndAddFlag) {
+ for (unsigned un = 0; un < unIndex; un++) {
+ unValue += (1 << ucTable[un]);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, ucTable[unIndex]);
+
+ unValue += bitStream.getBits(ucTable[unIndex]);
+ totalBitsUsed += ucTable[unIndex];
+ } else {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, ucTable[unIndex]);
+
+ unValue += bitStream.getBits(ucTable[unIndex]);
+ totalBitsUsed += ucTable[unIndex];
+ }
+ }
+
+ *bitsUsed = (size_t)totalBitsUsed;
+ *value = unValue;
+ return OK;
+}
+
+// Parse DTS UHD Profile-2 stream header
+static status_t parseDTSUHDSyncFrame(
+ const uint8_t *ptr, size_t size, unsigned &frameSize, sp<MetaData> *metaData) {
+
+ static const uint32_t DTSUHD_SYNC_CORE_16BIT_BE = 0x40411BF2;
+ static const uint32_t DTSUHD_NONSYNC_CORE_16BIT_BE = 0x71C442E8;
+
+ unsigned audioSamplRate = 0;
+
+ ABitReader bits(ptr, size);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 32);
+
+ uint32_t syncWord = bits.getBits(32);
+
+ bool isSyncFrameFlag = false;
+ switch (syncWord) {
+ case DTSUHD_SYNC_CORE_16BIT_BE:
+ isSyncFrameFlag = true;
+ break;
+ case DTSUHD_NONSYNC_CORE_16BIT_BE:
+ isSyncFrameFlag = false;
+ break;
+ default:
+ ALOGE("No valid sync word in DTSUHD header");
+ return ERROR_MALFORMED; // invalid sync word
+ }
+
+ unsigned uctable1[4] = { 5, 8, 10, 12 };
+ uint32_t sizeOfFTOCPayload = 0;
+ size_t nuBitsUsed = 0;
+ status_t status = OK;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &sizeOfFTOCPayload, uctable1, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+
+ if (isSyncFrameFlag) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1 + 2 + 3 + 2 + 1));
+
+ // FullChannelBasedMixFlag, ETSI TS 103 491 V1.2.1, Section 6.4.6.1
+ if (!(bits.getBits(1))) {
+ // This implementation only supports full channel mask-based
+ // audio presentation (i.e. 2.0, 5.1, 11.1 mix without objects)
+ ALOGE("Objects not supported, only DTSUHD full channel mask-based mix");
+ return ERROR_MALFORMED;
+ }
+
+ // BaseDuration, FrameDuration
+ bits.skipBits(2 + 3);
+
+ unsigned clockRateIndex = bits.getBits(2);
+ unsigned clockRateHertz = 0;
+
+ switch (clockRateIndex) {
+ case 0:
+ clockRateHertz = 32000;
+ break;
+ case 1:
+ clockRateHertz = 44100;
+ break;
+ case 2:
+ clockRateHertz = 48000;
+ break;
+ default:
+ ALOGE("Invalid clockRateIndex in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (32 + 4));
+
+ bits.skipBits(32 + 4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 2);
+
+ unsigned samplRateMultiplier = (1 << bits.getBits(2));
+ audioSamplRate = clockRateHertz * samplRateMultiplier;
+ }
+
+ uint32_t chunkPayloadBytes = 0;
+ int numOfMDChunks = isSyncFrameFlag ? 1 : 0; // Metadata chunks
+ for (int nmdc = 0; nmdc < numOfMDChunks; nmdc++) {
+ unsigned uctable2[4] = {6, 9, 12, 15};
+ uint32_t nuMDChunkSize = 0;
+ nuBitsUsed = 0;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &nuMDChunkSize, uctable2, true);
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+
+ if (nuMDChunkSize > 32767) {
+ ALOGE("Unsupported number of metadata chunks in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+ chunkPayloadBytes += nuMDChunkSize;
+ }
+
+ // Ony one audio chunk is supported
+ int numAudioChunks = 1;
+ for (int nac = 0; nac < numAudioChunks; nac++) {
+ uint32_t acID = 256, nuAudioChunkSize = 0;
+
+ // isSyncFrameFlag means that ACID is present
+ if (isSyncFrameFlag) {
+ unsigned uctable3[4] = {2, 4, 6, 8};
+ nuBitsUsed = 0;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &acID, uctable3, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+ }
+
+ nuBitsUsed = 0;
+ if (acID == 0) {
+ nuAudioChunkSize = 0;
+ } else {
+ unsigned uctable4[4] = {9, 11, 13, 16};
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &nuAudioChunkSize, uctable4, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+ }
+
+ if (nuAudioChunkSize > 65535){
+ ALOGE("Unsupported number of audio chunks in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ chunkPayloadBytes += nuAudioChunkSize;
+ }
+
+ frameSize = (sizeOfFTOCPayload + 1) + chunkPayloadBytes;
+
+ if (metaData != NULL) {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS_UHD);
+ (*metaData)->setInt32(kKeyAudioProfile, 0x2); // CodecProfileLevel.DTS_UHDProfileP2
+ (*metaData)->setInt32(kKeyChannelCount, 2); // Setting default channel count as stereo
+ (*metaData)->setInt32(kKeySampleRate, audioSamplRate);
+ }
+
+ return OK;
+}
+
+static status_t isSeeminglyValidDTSHDHeader(const uint8_t *ptr, size_t size,unsigned &frameSize)
+{
+ return parseDTSHDSyncFrame(ptr, size, frameSize, NULL);
+}
+
+static status_t isSeeminglyValidDTSUHDHeader(const uint8_t *ptr, size_t size,unsigned &frameSize)
+{
+ return parseDTSUHDSyncFrame(ptr, size, frameSize, NULL);
+}
+
static status_t IsSeeminglyValidAC4Header(const uint8_t *ptr, size_t size, unsigned &frameSize) {
return parseAC4SyncFrame(ptr, size, frameSize, NULL);
}
@@ -655,6 +1085,70 @@
break;
}
+ case DTS: // Checking for DTS or DTS-HD syncword
+ case DTS_HD:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+ unsigned frameSize = 0;
+ ssize_t startOffset = -1;
+
+ for (size_t i = 0; i < size; ++i) {
+ if (isSeeminglyValidDTSHDHeader(&ptr[i], size - i, frameSize) == OK) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+ if (startOffset > 0) {
+ ALOGI("found something resembling a DTS-HD syncword at "
+ "offset %zd",
+ startOffset);
+ }
+
+ if (frameSize != size - startOffset) {
+ ALOGV("DTS-HD frame size is %u bytes, while the buffer size is %zd bytes.",
+ frameSize, size - startOffset);
+ }
+
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
+ case DTS_UHD:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+ ssize_t startOffset = -1;
+ unsigned frameSize = 0;
+
+ for (size_t i = 0; i < size; ++i) {
+ if (isSeeminglyValidDTSUHDHeader(&ptr[i], size - i, frameSize) == OK) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+ if (startOffset >= 0) {
+ ALOGI("found something resembling a DTS UHD syncword"
+ "syncword at offset %zd",
+ startOffset);
+ }
+
+ if (frameSize != size - startOffset) {
+ ALOGV("DTS-UHD frame size is %u bytes, while the buffer size is %zd bytes.",
+ frameSize, size - startOffset);
+ }
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
case PCM_AUDIO:
case METADATA:
{
@@ -928,6 +1422,11 @@
return dequeueAccessUnitPCMAudio();
case METADATA:
return dequeueAccessUnitMetadata();
+ case DTS: // Using same dequeue function for both DTS and DTS-HD types.
+ case DTS_HD:
+ return dequeueAccessUnitDTSOrDTSHD();
+ case DTS_UHD:
+ return dequeueAccessUnitDTSUHD();
default:
if (mMode != MPEG_AUDIO) {
ALOGE("Unknown mode");
@@ -937,6 +1436,113 @@
}
}
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitDTSOrDTSHD() {
+ unsigned syncStartPos = 0; // in bytes
+ unsigned payloadSize = 0;
+ sp<MetaData> format = new MetaData;
+
+ ALOGV("dequeueAccessUnitDTSOrDTSHD[%d]: mBuffer %p(%zu)", mAUIndex,
+ mBuffer->data(), mBuffer->size());
+
+ while (true) {
+ if (syncStartPos + 4 >= mBuffer->size()) {
+ return NULL;
+ }
+ uint8_t *ptr = mBuffer->data() + syncStartPos;
+ size_t size = mBuffer->size() - syncStartPos;
+ status_t status = parseDTSHDSyncFrame(ptr, size, payloadSize, &format);
+ if (status == 0) {
+ break;
+ }
+ ++syncStartPos;
+ }
+
+ if (mBuffer->size() < syncStartPos + payloadSize) {
+ ALOGV("Not enough buffer size for DTS/DTS-HD");
+ return NULL;
+ }
+
+ if (mFormat == NULL) {
+ mFormat = format;
+ }
+
+ int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+ if (timeUs < 0LL) {
+ ALOGE("negative timeUs");
+ return NULL;
+ }
+ mAUIndex++;
+
+ sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+ memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+ accessUnit->meta()->setInt32("isSync", 1);
+
+ memmove(
+ mBuffer->data(),
+ mBuffer->data() + syncStartPos + payloadSize,
+ mBuffer->size() - syncStartPos - payloadSize);
+
+ mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+
+ return accessUnit;
+}
+
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitDTSUHD()
+{
+ unsigned syncStartPos = 0; // in bytes
+ unsigned payloadSize = 0;
+ sp<MetaData> format = new MetaData;
+
+ ALOGV("dequeueAccessUnitDTSUHD[%d]: mBuffer %p(%zu)", mAUIndex,
+ mBuffer->data(), mBuffer->size());
+
+ while (true) {
+ if (syncStartPos + 4 >= mBuffer->size()) {
+ return NULL;
+ }
+ uint8_t *ptr = mBuffer->data() + syncStartPos;
+ size_t size = mBuffer->size() - syncStartPos;
+ status_t status = parseDTSUHDSyncFrame(ptr, size, payloadSize, &format);
+ if (status == 0) {
+ break;
+ }
+ ++syncStartPos;
+ }
+
+ if (mBuffer->size() < syncStartPos + payloadSize) {
+ ALOGV("Not enough buffer size for DTS-UHD");
+ return NULL;
+ }
+
+ if (mFormat == NULL) {
+ mFormat = format;
+ }
+
+ int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+ if (timeUs < 0LL) {
+ ALOGE("negative timeUs");
+ return NULL;
+ }
+ mAUIndex++;
+
+ sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+ memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+ accessUnit->meta()->setInt32("isSync", 1);
+
+ memmove(
+ mBuffer->data(),
+ mBuffer->data() + syncStartPos + payloadSize,
+ mBuffer->size() - syncStartPos - payloadSize);
+
+ mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+
+ return accessUnit;
+}
+
sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitEAC3() {
unsigned syncStartPos = 0; // in bytes
unsigned payloadSize = 0;
diff --git a/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
index 49578d3..b658c5a 100644
--- a/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
+++ b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
@@ -157,6 +157,9 @@
STREAMTYPE_LPCM_AC3 = 0x83,
STREAMTYPE_EAC3 = 0x87,
+ // DTS audio stream type which contains only Core substream
+ STREAMTYPE_DTS = 0x8A,
+
//Sample Encrypted types
STREAMTYPE_H264_ENCRYPTED = 0xDB,
STREAMTYPE_AAC_ENCRYPTED = 0xCF,
@@ -168,6 +171,7 @@
DESCRIPTOR_CA = 0x09,
// DVB BlueBook A038 Table 12
+ DESCRIPTOR_DTS = 0x7B,
DESCRIPTOR_DVB_EXTENSION = 0x7F,
};
@@ -175,6 +179,8 @@
enum {
EXT_DESCRIPTOR_DVB_AC4 = 0x15,
EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION = 0x19,
+ EXT_DESCRIPTOR_DVB_DTS_HD = 0x0E,
+ EXT_DESCRIPTOR_DVB_DTS_UHD = 0x21,
EXT_DESCRIPTOR_DVB_RESERVED_MAX = 0x7F,
};
diff --git a/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
index a06bd6a..550a0e4 100644
--- a/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
+++ b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
@@ -45,6 +45,9 @@
MPEG4_VIDEO,
PCM_AUDIO,
METADATA,
+ DTS,
+ DTS_HD,
+ DTS_UHD,
};
enum Flags {
@@ -125,6 +128,8 @@
sp<ABuffer> dequeueAccessUnitMPEG4Video();
sp<ABuffer> dequeueAccessUnitPCMAudio();
sp<ABuffer> dequeueAccessUnitMetadata();
+ sp<ABuffer> dequeueAccessUnitDTSOrDTSHD();
+ sp<ABuffer> dequeueAccessUnitDTSUHD();
// consume a logical (compressed) access unit of size "size",
// returns its timestamp in us (or -1 if no time information).
diff --git a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
index 676345a..7dcdc3f 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
@@ -128,10 +128,10 @@
std::unique_ptr<IMtpHandle> handle;
if (mFdp.ConsumeBool()) {
std::unique_ptr<IMtpHandle> mtpCompactHandle(new MtpFfsCompatHandle(controlFd));
- handle = move(mtpCompactHandle);
+ handle = std::move(mtpCompactHandle);
} else {
std::unique_ptr<IMtpHandle> mtpHandle(new MtpFfsHandle(controlFd));
- handle = move(mtpHandle);
+ handle = std::move(mtpHandle);
}
int32_t mtpHandle = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxMtpHandleAPI);
diff --git a/services/tuner/hidl/TunerHidlDvr.cpp b/services/tuner/hidl/TunerHidlDvr.cpp
index 1a619d5..3ea1eb1 100644
--- a/services/tuner/hidl/TunerHidlDvr.cpp
+++ b/services/tuner/hidl/TunerHidlDvr.cpp
@@ -72,7 +72,7 @@
AidlMQDesc aidlMQDesc;
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(dvrMQDesc, &aidlMQDesc);
- *_aidl_return = move(aidlMQDesc);
+ *_aidl_return = std::move(aidlMQDesc);
return ::ndk::ScopedAStatus::ok();
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index fe74a5c..c82732b 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -139,7 +139,7 @@
AidlMQDesc aidlMQDesc;
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(filterMQDesc, &aidlMQDesc);
- *_aidl_return = move(aidlMQDesc);
+ *_aidl_return = std::move(aidlMQDesc);
return ::ndk::ScopedAStatus::ok();
}
@@ -1084,8 +1084,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::media>(move(media));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::media>(std::move(media));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1101,8 +1101,8 @@
section.dataLength = static_cast<int64_t>(sectionEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::section>(move(section));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::section>(std::move(section));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1117,8 +1117,8 @@
pes.mpuSequenceNumber = static_cast<int32_t>(pesEvent.mpuSequenceNumber);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::pes>(move(pes));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::pes>(std::move(pes));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1167,8 +1167,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::tsRecord>(move(tsRecord));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::tsRecord>(std::move(tsRecord));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1194,8 +1194,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::mmtpRecord>(move(mmtpRecord));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::mmtpRecord>(std::move(mmtpRecord));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1213,8 +1213,8 @@
download.dataLength = static_cast<int32_t>(downloadEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::download>(move(download));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::download>(std::move(download));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1227,8 +1227,8 @@
ipPayload.dataLength = static_cast<int32_t>(ipPayloadEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::ipPayload>(move(ipPayload));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::ipPayload>(std::move(ipPayload));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1245,8 +1245,8 @@
copy(descrData.begin(), descrData.end(), temi.descrData.begin());
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::temi>(move(temi));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::temi>(std::move(temi));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1268,15 +1268,15 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::monitorEvent>(move(monitor));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::monitorEvent>(std::move(monitor));
+ res.push_back(std::move(filterEvent));
}
void TunerHidlFilter::FilterCallback::getRestartEvent(
const vector<HidlDemuxFilterEventExt::Event>& eventsExt, vector<DemuxFilterEvent>& res) {
DemuxFilterEvent filterEvent;
filterEvent.set<DemuxFilterEvent::startId>(static_cast<int32_t>(eventsExt[0].startId()));
- res.push_back(move(filterEvent));
+ res.push_back(std::move(filterEvent));
}
} // namespace tuner