[automerger skipped] Merge "vts: Disable checking md5 checksum and timestamps for tunneled decoders" into android14-tests-dev am: 8d43abd037 am: c015e55065 -s ours
am skip reason: Merged-In Icf734efb07c28f469da93c04285457bccbfc2a28 with SHA-1 7291152bb5 is already in history
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/3222363
Change-Id: I058d10fb9a0c9e8efa866964d200711ee7eeb969
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index f36a743..0c80e7e 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -177,14 +177,11 @@
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
- do {
- binder = sm->getService(toString16(kCameraServiceName));
- if (binder != nullptr) {
- break;
- }
- ALOGW("CameraService not published, waiting...");
- usleep(kCameraServicePollDelay);
- } while(true);
+ binder = sm->checkService(String16(kCameraServiceName));
+ if (binder == nullptr) {
+ ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
+ return nullptr;
+ }
if (mDeathNotifier == nullptr) {
mDeathNotifier = new DeathNotifier(this);
}
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index d8bf6b1..f4124ef 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -99,7 +99,6 @@
private:
sp<hardware::ICameraService> mCameraService;
- const int kCameraServicePollDelay = 500000; // 0.5s
const char* kCameraServiceName = "media.camera";
Mutex mLock;
diff --git a/drm/mediadrm/plugins/clearkey/aidl/Android.bp b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
index 9a06bd2..8e8e57d 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
@@ -11,13 +11,13 @@
name: "aidl_clearkey_service_defaults-use-shared-deps",
shared_libs: [
+ "android.hardware.drm-V1-ndk",
"libbase",
"libbinder_ndk",
"libcrypto",
"liblog",
"libprotobuf-cpp-lite",
"libutils",
- "android.hardware.drm-V1-ndk",
],
static_libs: [
@@ -62,7 +62,11 @@
relative_install_path: "hw",
- cflags: ["-Wall", "-Werror", "-Wthread-safety"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wthread-safety",
+ ],
include_dirs: ["frameworks/av/include"],
@@ -137,18 +141,22 @@
relative_install_path: "hw",
- cflags: ["-Wall", "-Werror", "-Wthread-safety"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wthread-safety",
+ ],
include_dirs: ["frameworks/av/include"],
shared_libs: [
+ "android.hardware.drm-V1-ndk",
"libbase",
"libbinder_ndk",
"libcrypto",
"liblog",
"libprotobuf-cpp-lite",
"libutils",
- "android.hardware.drm-V1-ndk",
],
static_libs: [
@@ -192,7 +200,7 @@
],
prebuilts: [
"android.hardware.drm-service.clearkey.apex.rc",
- "android.hardware.drm-service.clearkey.xml"
+ "android.hardware.drm-service.clearkey.xml",
],
overrides: [
"android.hardware.drm-service.clearkey",
@@ -233,11 +241,11 @@
],
prebuilts: [
"android.hardware.drm-service-lazy.clearkey.apex.rc",
- "android.hardware.drm-service.clearkey.xml"
+ "android.hardware.drm-service.clearkey.xml",
],
overrides: [
- "android.hardware.drm-service.clearkey",
"android.hardware.drm-service-lazy.clearkey",
+ "android.hardware.drm-service.clearkey",
"com.android.hardware.drm.clearkey",
],
}
diff --git a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
index 31cb7c0..8a93132 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
@@ -37,7 +37,6 @@
const int kSecureStopIdStart = 100;
const std::string kOfflineLicense("\"type\":\"persistent-license\"");
const std::string kStreaming("Streaming");
-const std::string kTemporaryLicense("\"type\":\"temporary\"");
const std::string kTrue("True");
const std::string kQueryKeyLicenseType("LicenseType");
diff --git a/drm/mediadrm/plugins/clearkey/common/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/common/JsonWebKey.cpp
index ddbc594..cd129ac 100644
--- a/drm/mediadrm/plugins/clearkey/common/JsonWebKey.cpp
+++ b/drm/mediadrm/plugins/clearkey/common/JsonWebKey.cpp
@@ -27,10 +27,7 @@
const std::string kKeyTypeTag("kty");
const std::string kKeyTag("k");
const std::string kKeyIdTag("kid");
-const std::string kMediaSessionType("type");
-const std::string kPersistentLicenseSession("persistent-license");
const std::string kSymmetricKeyValue("oct");
-const std::string kTemporaryLicenseSession("temporary");
} // namespace
namespace clearkeydrm {
diff --git a/media/audioserver/Android.bp b/media/audioserver/Android.bp
index ac2fcbe..47b48e3 100644
--- a/media/audioserver/Android.bp
+++ b/media/audioserver/Android.bp
@@ -20,13 +20,6 @@
"-Werror",
],
- header_libs: [
- "audiopolicyservicelocal_headers",
- "libaudiohal_headers",
- "libmedia_headers",
- "libmediametrics_headers",
- ],
-
defaults: [
"latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_media_audio_common_types_cpp_shared",
@@ -40,39 +33,10 @@
"libaudioflinger",
"libaudiopolicyservice",
"libmedialogservice",
- "libnbaio",
],
shared_libs: [
- "libaudioclient",
- "libaudioprocessing",
- "libbinder",
- "libcutils",
- "libhidlbase",
- "liblog",
- "libmedia",
- "libmediautils",
- "libnblog",
- "libpowermanager",
- "libutils",
- "libvibrator",
- ],
-
- // TODO check if we still need all of these include directories
- include_dirs: [
- "external/sonic",
- "frameworks/av/media/libaaudio/include",
- "frameworks/av/media/libaaudio/src",
- "frameworks/av/media/libaaudio/src/binding",
- "frameworks/av/services/audioflinger",
- "frameworks/av/services/audiopolicy",
- "frameworks/av/services/audiopolicy/common/include",
- "frameworks/av/services/audiopolicy/common/managerdefinitions/include",
- "frameworks/av/services/audiopolicy/engine/interface",
- "frameworks/av/services/audiopolicy/service",
- "frameworks/av/services/medialog",
- "frameworks/av/services/oboeservice", // TODO oboeservice is the old folder name for aaudioservice. It will be changed.
-
+ "libhidlbase", // required for threadpool config.
],
init_rc: ["audioserver.rc"],
diff --git a/media/codec2/hal/common/MultiAccessUnitHelper.cpp b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
index 55bf7a9..b287b91 100644
--- a/media/codec2/hal/common/MultiAccessUnitHelper.cpp
+++ b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
@@ -327,10 +327,10 @@
newWork->worklets.front()->component = inWork->worklets.front()->component;
std::vector<std::unique_ptr<C2Tuning>> tunings;
for (std::unique_ptr<C2Tuning>& tuning : inWork->worklets.front()->tunings) {
- tunings.push_back(std::move(
+ tunings.push_back(
std::unique_ptr<C2Tuning>(
static_cast<C2Tuning*>(
- C2Param::Copy(*(tuning.get())).release()))));
+ C2Param::Copy(*(tuning.get())).release())));
}
newWork->worklets.front()->tunings = std::move(tunings);
}
@@ -344,7 +344,7 @@
<< inputOrdinal.frameIndex.peekull()
<< ") -> newFrameIndex " << newFrameIdx
<<" : input ts " << inputOrdinal.timestamp.peekull();
- sliceWork.push_back(std::move(cloneInputWork(w, w->input.flags)));
+ sliceWork.push_back(cloneInputWork(w, w->input.flags));
if (!w->input.buffers.empty() && w->input.buffers.front() != nullptr) {
sliceWork.back()->input.buffers = std::move(w->input.buffers);
}
@@ -853,4 +853,4 @@
mLargeWork.reset();
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index ae66a58..373f86e 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -222,19 +222,20 @@
~HGraphicBufferSourceWrapper() override = default;
status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
- mNode = new C2OMXNode(comp);
- mOmxNode = new hardware::media::omx::V1_0::utils::TWOmxNode(mNode);
- mNode->setFrameSize(mWidth, mHeight);
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ *node = new C2OMXNode(comp);
+ mOmxNode = new hardware::media::omx::V1_0::utils::TWOmxNode(*node);
+ (*node)->setFrameSize(mWidth, mHeight);
// Usage is queried during configure(), so setting it beforehand.
// 64 bit set parameter is existing only in C2OMXNode.
OMX_U64 usage64 = mConfig.mUsage;
- status_t res = mNode->setParameter(
+ status_t res = (*node)->setParameter(
(OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits64,
&usage64, sizeof(usage64));
if (res != OK) {
OMX_U32 usage = mConfig.mUsage & 0xFFFFFFFF;
- (void)mNode->setParameter(
+ (void)(*node)->setParameter(
(OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
&usage, sizeof(usage));
}
@@ -244,17 +245,18 @@
}
void disconnect() override {
- if (mNode == nullptr) {
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
return;
}
- sp<IOMXBufferSource> source = mNode->getSource();
+ sp<IOMXBufferSource> source = (*node)->getSource();
if (source == nullptr) {
ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
return;
}
source->onOmxIdle();
source->onOmxLoaded();
- mNode.clear();
+ node->clear();
mOmxNode.clear();
}
@@ -268,7 +270,11 @@
}
status_t start() override {
- sp<IOMXBufferSource> source = mNode->getSource();
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return NO_INIT;
+ }
+ sp<IOMXBufferSource> source = (*node)->getSource();
if (source == nullptr) {
return NO_INIT;
}
@@ -278,7 +284,7 @@
OMX_PARAM_PORTDEFINITIONTYPE param;
param.nPortIndex = kPortIndexInput;
- status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
+ status_t err = (*node)->getParameter(OMX_IndexParamPortDefinition,
¶m, sizeof(param));
if (err == OK) {
numSlots = param.nBufferCountActual;
@@ -297,6 +303,7 @@
}
status_t configure(Config &config) {
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
std::stringstream status;
status_t err = OK;
@@ -317,7 +324,7 @@
// pts gap
if (config.mMinAdjustedFps > 0 || config.mFixedAdjustedFps > 0) {
- if (mNode != nullptr) {
+ if ((*node) != nullptr) {
OMX_PARAM_U32TYPE ptrGapParam = {};
ptrGapParam.nSize = sizeof(OMX_PARAM_U32TYPE);
float gap = (config.mMinAdjustedFps > 0)
@@ -326,7 +333,7 @@
// float -> uint32_t is undefined if the value is negative.
// First convert to int32_t to ensure the expected behavior.
ptrGapParam.nU32 = int32_t(gap);
- (void)mNode->setParameter(
+ (void)(*node)->setParameter(
(OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
&ptrGapParam, sizeof(ptrGapParam));
}
@@ -426,8 +433,8 @@
// priority
if (mConfig.mPriority != config.mPriority) {
- if (config.mPriority != INT_MAX) {
- mNode->setPriority(config.mPriority);
+ if (config.mPriority != INT_MAX && (*node) != nullptr) {
+ (*node)->setPriority(config.mPriority);
}
mConfig.mPriority = config.mPriority;
}
@@ -441,24 +448,40 @@
}
void onInputBufferDone(c2_cntr64_t index) override {
- mNode->onInputBufferDone(index);
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return;
+ }
+ (*node)->onInputBufferDone(index);
}
void onInputBufferEmptied() override {
- mNode->onInputBufferEmptied();
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return;
+ }
+ (*node)->onInputBufferEmptied();
}
android_dataspace getDataspace() override {
- return mNode->getDataspace();
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return HAL_DATASPACE_UNKNOWN;
+ }
+ return (*node)->getDataspace();
}
uint32_t getPixelFormat() override {
- return mNode->getPixelFormat();
+ Mutexed<sp<C2OMXNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+ return (*node)->getPixelFormat();
}
private:
sp<HGraphicBufferSource> mSource;
- sp<C2OMXNode> mNode;
+ Mutexed<sp<C2OMXNode>> mNode;
sp<hardware::media::omx::V1_0::IOmxNode> mOmxNode;
uint32_t mWidth;
uint32_t mHeight;
@@ -479,33 +502,39 @@
~AGraphicBufferSourceWrapper() override = default;
status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
- mNode = ::ndk::SharedRefBase::make<C2AidlNode>(comp);
- mNode->setFrameSize(mWidth, mHeight);
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ *node = ::ndk::SharedRefBase::make<C2AidlNode>(comp);
+ (*node)->setFrameSize(mWidth, mHeight);
// Usage is queried during configure(), so setting it beforehand.
uint64_t usage = mConfig.mUsage;
- (void)mNode->setConsumerUsage((int64_t)usage);
+ (void)(*node)->setConsumerUsage((int64_t)usage);
return fromAidlStatus(mSource->configure(
- mNode, static_cast<::aidl::android::hardware::graphics::common::Dataspace>(
+ (*node), static_cast<::aidl::android::hardware::graphics::common::Dataspace>(
mDataSpace)));
}
void disconnect() override {
- if (mNode == nullptr) {
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
return;
}
- std::shared_ptr<IAidlBufferSource> source = mNode->getSource();
+ std::shared_ptr<IAidlBufferSource> source = (*node)->getSource();
if (source == nullptr) {
ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
return;
}
(void)source->onStop();
(void)source->onRelease();
- mNode.reset();
+ node->reset();
}
status_t start() override {
- std::shared_ptr<IAidlBufferSource> source = mNode->getSource();
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return NO_INIT;
+ }
+ std::shared_ptr<IAidlBufferSource> source = (*node)->getSource();
if (source == nullptr) {
return NO_INIT;
}
@@ -513,7 +542,7 @@
size_t numSlots = 16;
IAidlNode::InputBufferParams param;
- status_t err = fromAidlStatus(mNode->getInputBufferParams(¶m));
+ status_t err = fromAidlStatus((*node)->getInputBufferParams(¶m));
if (err == OK) {
numSlots = param.bufferCountActual;
}
@@ -531,6 +560,7 @@
}
status_t configure(Config &config) {
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
std::stringstream status;
status_t err = OK;
@@ -551,14 +581,14 @@
// pts gap
if (config.mMinAdjustedFps > 0 || config.mFixedAdjustedFps > 0) {
- if (mNode != nullptr) {
+ if ((*node) != nullptr) {
float gap = (config.mMinAdjustedFps > 0)
? c2_min(INT32_MAX + 0., 1e6 / config.mMinAdjustedFps + 0.5)
: c2_max(0. - INT32_MAX, -1e6 / config.mFixedAdjustedFps - 0.5);
// float -> uint32_t is undefined if the value is negative.
// First convert to int32_t to ensure the expected behavior.
int32_t gapUs = int32_t(gap);
- (void)mNode->setAdjustTimestampGapUs(gapUs);
+ (void)(*node)->setAdjustTimestampGapUs(gapUs);
}
}
@@ -650,7 +680,7 @@
// priority
if (mConfig.mPriority != config.mPriority) {
if (config.mPriority != INT_MAX) {
- mNode->setPriority(config.mPriority);
+ (*node)->setPriority(config.mPriority);
}
mConfig.mPriority = config.mPriority;
}
@@ -664,24 +694,40 @@
}
void onInputBufferDone(c2_cntr64_t index) override {
- mNode->onInputBufferDone(index);
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return;
+ }
+ (*node)->onInputBufferDone(index);
}
void onInputBufferEmptied() override {
- mNode->onInputBufferEmptied();
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return;
+ }
+ (*node)->onInputBufferEmptied();
}
android_dataspace getDataspace() override {
- return mNode->getDataspace();
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return HAL_DATASPACE_UNKNOWN;
+ }
+ return (*node)->getDataspace();
}
uint32_t getPixelFormat() override {
- return mNode->getPixelFormat();
+ Mutexed<std::shared_ptr<C2AidlNode>>::Locked node(mNode);
+ if ((*node) == nullptr) {
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+ return (*node)->getPixelFormat();
}
private:
std::shared_ptr<AGraphicBufferSource> mSource;
- std::shared_ptr<C2AidlNode> mNode;
+ Mutexed<std::shared_ptr<C2AidlNode>> mNode;
uint32_t mWidth;
uint32_t mHeight;
Config mConfig;
@@ -2627,7 +2673,7 @@
mChannel->setInfoBuffer(std::make_shared<C2InfoBuffer>(info));
}
} else {
- ALOGE("Ignoring param key %s as buffer size %d is less than expected "
+ ALOGE("Ignoring param key %s as buffer size %zu is less than expected "
"buffer size %d",
PARAMETER_KEY_QP_OFFSET_MAP, mapSize, expectedMapSize);
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 1348ef0..d829523 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -228,15 +228,17 @@
status_t CCodecBufferChannel::setInputSurface(
const std::shared_ptr<InputSurfaceWrapper> &surface) {
ALOGV("[%s] setInputSurface", mName);
- mInputSurface = surface;
- return mInputSurface->connect(mComponent);
+ Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
+ *inputSurface = surface;
+ return (*inputSurface)->connect(mComponent);
}
status_t CCodecBufferChannel::signalEndOfInputStream() {
- if (mInputSurface == nullptr) {
+ Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
+ if ((*inputSurface) == nullptr) {
return INVALID_OPERATION;
}
- return mInputSurface->signalEndOfInputStream();
+ return (*inputSurface)->signalEndOfInputStream();
}
status_t CCodecBufferChannel::queueInputBufferInternal(
@@ -1069,9 +1071,11 @@
return;
}
}
- if (android::media::codec::provider_->input_surface_throttle()
- && mInputSurface != nullptr) {
- mInputSurface->onInputBufferEmptied();
+ if (android::media::codec::provider_->input_surface_throttle()) {
+ Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
+ if ((*inputSurface) != nullptr) {
+ (*inputSurface)->onInputBufferEmptied();
+ }
}
size_t numActiveSlots = 0;
while (!mPipelineWatcher.lock()->pipelineFull()) {
@@ -1700,7 +1704,7 @@
&& (hasCryptoOrDescrambler() || conforming)) {
input->buffers.reset(new SlotInputBuffers(mName));
} else if (graphic) {
- if (mInputSurface) {
+ if (mInputSurface.lock()->get()) {
input->buffers.reset(new DummyInputBuffers(mName));
} else if (mMetaMode == MODE_ANW) {
input->buffers.reset(new GraphicMetadataInputBuffers(mName));
@@ -1983,7 +1987,7 @@
status_t CCodecBufferChannel::prepareInitialInputBuffers(
std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers, bool retry) {
- if (mInputSurface) {
+ if (mInputSurface.lock()->get()) {
return OK;
}
@@ -2109,9 +2113,7 @@
void CCodecBufferChannel::reset() {
stop();
- if (mInputSurface != nullptr) {
- mInputSurface.reset();
- }
+ mInputSurface.lock()->reset();
mPipelineWatcher.lock()->flush();
{
Mutexed<Input>::Locked input(mInput);
@@ -2206,7 +2208,7 @@
void CCodecBufferChannel::onInputBufferDone(
uint64_t frameIndex, size_t arrayIndex) {
- if (mInputSurface) {
+ if (mInputSurface.lock()->get()) {
return;
}
std::shared_ptr<C2Buffer> buffer =
@@ -2263,7 +2265,8 @@
notifyClient = false;
}
- if (mInputSurface == nullptr && (work->worklets.size() != 1u
+ bool hasInputSurface = (mInputSurface.lock()->get() != nullptr);
+ if (!hasInputSurface && (work->worklets.size() != 1u
|| !work->worklets.front()
|| !(work->worklets.front()->output.flags &
C2FrameData::FLAG_INCOMPLETE))) {
@@ -2472,7 +2475,7 @@
c2_cntr64_t timestamp =
worklet->output.ordinal.timestamp + work->input.ordinal.customOrdinal
- work->input.ordinal.timestamp;
- if (mInputSurface != nullptr) {
+ if (hasInputSurface) {
// When using input surface we need to restore the original input timestamp.
timestamp = work->input.ordinal.customOrdinal;
}
@@ -2799,7 +2802,7 @@
}
void CCodecBufferChannel::setInfoBuffer(const std::shared_ptr<C2InfoBuffer> &buffer) {
- if (mInputSurface == nullptr) {
+ if (mInputSurface.lock()->get() == nullptr) {
mInfoBuffers.push_back(buffer);
} else {
std::list<std::unique_ptr<C2Work>> items;
@@ -2807,7 +2810,6 @@
work->input.infoBuffers.emplace_back(*buffer);
work->worklets.emplace_back(new C2Worklet);
items.push_back(std::move(work));
- c2_status_t err = mComponent->queue(&items);
}
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index e62742b..f5e268a 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -391,7 +391,7 @@
};
Mutexed<BlockPools> mBlockPools;
- std::shared_ptr<InputSurfaceWrapper> mInputSurface;
+ Mutexed<std::shared_ptr<InputSurfaceWrapper>> mInputSurface;
MetaMode mMetaMode;
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
index 11955c9..61d5ccd 100644
--- a/media/libaudioclient/aidl/fuzzer/Android.bp
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -28,53 +28,20 @@
"libcgrouprc_format",
"libfakeservicemanager",
"libjsoncpp",
- "liblog",
- "libmedia_helper",
"libmediametricsservice",
"libprocessgroup",
"shared-file-region-aidl-cpp",
],
shared_libs: [
"android.hardware.audio.common-util",
- "audioclient-types-aidl-cpp",
- "audioflinger-aidl-cpp",
- "audiopolicy-aidl-cpp",
- "audiopolicy-types-aidl-cpp",
- "av-types-aidl-cpp",
- "capture_state_listener-aidl-cpp",
- "effect-aidl-cpp",
- "framework-permission-aidl-cpp",
- "libactivitymanager_aidl",
- "libaudioclient",
- "libaudioclient_aidl_conversion",
"libaudioflinger",
- "libaudiofoundation",
- "libaudiohal",
- "libaudiomanager",
- "libaudiopolicy",
- "libaudiopolicymanagerdefault",
"libaudiopolicyservice",
- "libaudioprocessing",
- "libaudioutils",
"libdl",
- "libheadtracking",
- "libmediametrics",
- "libmediautils",
- "libnbaio",
- "libnblog",
- "libpowermanager",
- "libvibrator",
"libvndksupport",
- "libxml2",
"mediametricsservice-aidl-cpp",
- "packagemanager_aidl-cpp",
],
header_libs: [
- "libaudioflinger_headers",
- "libaudiofoundation_headers",
- "libaudiohal_headers",
"libaudiopolicymanager_interface_headers",
- "libbinder_headers",
"libmedia_headers",
],
fuzz_config: {
@@ -99,6 +66,8 @@
"latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
"libaudioclient_aidl_fuzzer_defaults",
+ "libaudioflinger_dependencies",
+ "libaudiopolicyservice_dependencies",
"service_fuzzer_defaults",
],
}
diff --git a/media/libaudioclient/tests/audioeffect_tests.cpp b/media/libaudioclient/tests/audioeffect_tests.cpp
index 59d0c6a..bedeff9 100644
--- a/media/libaudioclient/tests/audioeffect_tests.cpp
+++ b/media/libaudioclient/tests/audioeffect_tests.cpp
@@ -70,8 +70,8 @@
return effect;
}
-status_t isEffectExistsOnAudioSession(const effect_uuid_t* type, const effect_uuid_t* uuid,
- int priority, audio_session_t sessionId) {
+status_t createAndInitCheckEffect(const effect_uuid_t* type, const effect_uuid_t* uuid,
+ int priority, audio_session_t sessionId) {
sp<AudioEffect> effect = createEffect(type, uuid, priority, sessionId);
return effect->initCheck();
}
@@ -272,10 +272,9 @@
EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
capture->getAudioRecordHandle()))
<< "Effect should not have been default on record. " << type;
- EXPECT_EQ(NO_ERROR,
- isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
- kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ EXPECT_EQ(NO_ERROR, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should not have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
@@ -296,9 +295,9 @@
capture->getAudioRecordHandle()))
<< "Effect should have been default on record. " << type;
EXPECT_EQ(ALREADY_EXISTS,
- isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
- kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
@@ -313,10 +312,9 @@
EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
capture->getAudioRecordHandle()))
<< "Effect should not have been default on record. " << type;
- EXPECT_EQ(NO_ERROR,
- isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
- kDefaultInputEffectPriority - 1,
- capture->getAudioRecordHandle()->getSessionId()))
+ EXPECT_EQ(NO_ERROR, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
<< "Effect should not have been added. " << type;
EXPECT_EQ(OK, capture->audioProcess());
EXPECT_EQ(OK, capture->stop());
@@ -421,8 +419,8 @@
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
- isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
+ createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
<< "Effect should not have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
playback->stop();
@@ -445,8 +443,8 @@
EXPECT_EQ(NO_ERROR, playback->start());
// If effect chosen is not compatible with the session, then effect won't be applied
EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
- isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
+ createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
<< "Effect should have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
if (mSelectFastMode) {
@@ -467,8 +465,8 @@
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
- isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
- playback->getAudioTrackHandle()->getSessionId()))
+ createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
<< "Effect should not have been added. " << mTypeStr;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
playback->stop();
@@ -502,8 +500,8 @@
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
- EXPECT_EQ(ALREADY_EXISTS, isEffectExistsOnAudioSession(
- &mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
+ EXPECT_EQ(ALREADY_EXISTS,
+ createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
<< "Effect should have been added. " << mTypeStr;
if (mSelectFastMode) {
EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
@@ -556,8 +554,8 @@
ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
EXPECT_EQ(NO_ERROR, playback->create());
EXPECT_EQ(NO_ERROR, playback->start());
- EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
- kDefaultOutputEffectPriority - 1, sessionId))
+ ASSERT_EQ(ALREADY_EXISTS, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultOutputEffectPriority - 1, sessionId))
<< "Effect should have been added. " << type;
EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
playback->stop();
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 639c7aa..75e2c11 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -45,6 +45,8 @@
"liberror_headers",
"libmediautils_headers",
],
+
+ export_include_dirs: ["include"],
}
cc_library_shared {
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 024589b..976c1f6 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -488,8 +488,11 @@
*outStream = stream;
/* StreamOutHalInterface* */ void* cbCookie = (*outStream).get();
{
- std::lock_guard l(mLock);
+ std::lock_guard l(mCallbacksLock);
mCallbacks.emplace(cbCookie, Callbacks{});
+ }
+ {
+ std::lock_guard l(mLock);
mMapper.addStream(*outStream, mixPortConfig.id, aidlPatch.id);
}
if (streamCb) {
@@ -1331,7 +1334,7 @@
}
void DeviceHalAidl::clearCallbacks(void* cookie) {
- std::lock_guard l(mLock);
+ std::lock_guard l(mCallbacksLock);
mCallbacks.erase(cookie);
}
@@ -1364,18 +1367,21 @@
setCallbackImpl(cookie, &Callbacks::latency, cb);
}
-template<class C>
+template <class C>
sp<C> DeviceHalAidl::getCallbackImpl(void* cookie, wp<C> DeviceHalAidl::Callbacks::* field) {
- std::lock_guard l(mLock);
- if (auto it = mCallbacks.find(cookie); it != mCallbacks.end()) {
- return ((it->second).*field).promote();
+ wp<C> result;
+ {
+ std::lock_guard l(mCallbacksLock);
+ if (auto it = mCallbacks.find(cookie); it != mCallbacks.end()) {
+ result = (it->second).*field;
+ }
}
- return nullptr;
+ return result.promote();
}
template<class C>
void DeviceHalAidl::setCallbackImpl(
void* cookie, wp<C> DeviceHalAidl::Callbacks::* field, const sp<C>& cb) {
- std::lock_guard l(mLock);
+ std::lock_guard l(mCallbacksLock);
if (auto it = mCallbacks.find(cookie); it != mCallbacks.end()) {
(it->second).*field = cb;
}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index bcd495d..08455f1 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -242,8 +242,11 @@
const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothLe> mBluetoothLe;
const std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose> mSoundDose;
+ std::mutex mCallbacksLock;
+ // Use 'mCallbacksLock' only to implement exclusive access to 'mCallbacks'. Never hold it
+ // while making any calls.
+ std::map<void*, Callbacks> mCallbacks GUARDED_BY(mCallbacksLock);
std::mutex mLock;
- std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
std::set<audio_port_handle_t> mDeviceDisconnectionNotified GUARDED_BY(mLock);
Hal2AidlMapper mMapper GUARDED_BY(mLock);
LockedAccessor<Hal2AidlMapper> mMapperAccessor;
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 740bf60..2753906 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -42,6 +42,8 @@
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Processing;
+using ::aidl::android::media::audio::common::AudioDevice;
+using ::aidl::android::media::audio::common::AudioDeviceAddress;
using ::aidl::android::media::audio::common::AudioSource;
using ::aidl::android::media::audio::common::AudioStreamType;
using ::aidl::android::media::audio::common::AudioUuid;
@@ -281,7 +283,8 @@
auto getConfigProcessingWithAidlProcessing =
[&](const auto& aidlProcess, std::vector<effectsConfig::InputStream>& preprocess,
- std::vector<effectsConfig::OutputStream>& postprocess) {
+ std::vector<effectsConfig::OutputStream>& postprocess,
+ std::vector<effectsConfig::DeviceEffects>& deviceprocess) {
if (aidlProcess.type.getTag() == Processing::Type::streamType) {
AudioStreamType aidlType =
aidlProcess.type.template get<Processing::Type::streamType>();
@@ -313,6 +316,25 @@
effectsConfig::InputStream stream = {.type = type.value(),
.effects = std::move(effects)};
preprocess.emplace_back(stream);
+ } else if (aidlProcess.type.getTag() == Processing::Type::device) {
+ AudioDevice aidlDevice =
+ aidlProcess.type.template get<Processing::Type::device>();
+ std::vector<std::shared_ptr<const effectsConfig::Effect>> effects;
+ std::transform(aidlProcess.ids.begin(), aidlProcess.ids.end(),
+ std::back_inserter(effects), getConfigEffectWithDescriptor);
+ audio_devices_t type;
+ char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+ status_t status = ::aidl::android::aidl2legacy_AudioDevice_audio_device(
+ aidlDevice, &type, address);
+ if (status != NO_ERROR) {
+ ALOGE("%s device effect has invalid device type / address", __func__);
+ return;
+ }
+ effectsConfig::DeviceEffects device = {
+ {.type = type, .effects = std::move(effects)},
+ .address = address,
+ };
+ deviceprocess.emplace_back(device);
}
};
@@ -320,17 +342,21 @@
[&]() -> std::shared_ptr<const effectsConfig::Processings> {
std::vector<effectsConfig::InputStream> preprocess;
std::vector<effectsConfig::OutputStream> postprocess;
+ std::vector<effectsConfig::DeviceEffects> deviceprocess;
for (const auto& processing : mAidlProcessings) {
- getConfigProcessingWithAidlProcessing(processing, preprocess, postprocess);
+ getConfigProcessingWithAidlProcessing(processing, preprocess, postprocess,
+ deviceprocess);
}
- if (0 == preprocess.size() && 0 == postprocess.size()) {
+ if (0 == preprocess.size() && 0 == postprocess.size() &&
+ 0 == deviceprocess.size()) {
return nullptr;
}
return std::make_shared<const effectsConfig::Processings>(
effectsConfig::Processings({.preprocess = std::move(preprocess),
- .postprocess = std::move(postprocess)}));
+ .postprocess = std::move(postprocess),
+ .deviceprocess = std::move(deviceprocess)}));
}());
return processings;
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 030ee2b..918f886 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -421,8 +421,16 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- return sendCommand(makeHalCommand<HalCommand::Tag::pause>(), reply,
- true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+
+ if (const auto state = getState(); isInPlayOrRecordState(state)) {
+ return sendCommand(
+ makeHalCommand<HalCommand::Tag::pause>(), reply,
+ true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+ } else {
+ ALOGD("%s: already stream in one of the PAUSED kind of states, current state: %s", __func__,
+ toString(state).c_str());
+ return OK;
+ }
}
status_t StreamHalAidl::resume(StreamDescriptor::Reply* reply) {
@@ -477,8 +485,19 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- return sendCommand(makeHalCommand<HalCommand::Tag::flush>(), reply,
- true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+
+ if (const auto state = getState(); isInPausedState(state)) {
+ return sendCommand(
+ makeHalCommand<HalCommand::Tag::flush>(), reply,
+ true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+ } else if (isInPlayOrRecordState(state)) {
+ ALOGE("%s: found stream in non-flushable state: %s", __func__, toString(state).c_str());
+ return INVALID_OPERATION;
+ } else {
+ ALOGD("%s: already stream in one of the flushable state: current state: %s", __func__,
+ toString(state).c_str());
+ return OK;
+ }
}
status_t StreamHalAidl::exit() {
@@ -802,9 +821,9 @@
status_t StreamOutHalAidl::drain(bool earlyNotify) {
if (!mStream) return NO_INIT;
- if(const auto state = getState(); state == StreamDescriptor::State::IDLE) {
- ALOGD("%p %s stream already in IDLE state", this, __func__);
- if(mContext.isAsynchronous()) onDrainReady();
+ if (const auto state = getState(); isInDrainedState(state)) {
+ ALOGD("%p %s stream already in %s", this, __func__, toString(state).c_str());
+ if (mContext.isAsynchronous()) onDrainReady();
return OK;
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 0587640..baf4ac0 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -220,6 +220,41 @@
return mLastReply.state;
}
+ bool isInDrainedState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::IDLE ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::STANDBY) {
+ // drain equivalent states
+ return true;
+ }
+ return false;
+ }
+
+ bool isInPlayOrRecordState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::ACTIVE ||
+ state ==
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State::TRANSFERRING ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAINING) {
+ // play or record equivalent states
+ return true;
+ }
+ return false;
+ }
+
+ bool isInPausedState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State& state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::PAUSED ||
+ state ==
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAIN_PAUSED ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::
+ TRANSFER_PAUSED) {
+ // pause equivalent states
+ return true;
+ }
+ return false;
+ }
+
status_t getLatency(uint32_t *latency);
// Always returns non-negative values.
diff --git a/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
index 50b748e..dbd1f60 100644
--- a/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
+++ b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
@@ -18,6 +18,7 @@
#include <memory>
#include <mutex>
#include <string>
+#include <thread>
#include <vector>
#define LOG_TAG "CoreAudioHalAidlTest"
@@ -28,6 +29,7 @@
#include <StreamHalAidl.h>
#include <aidl/android/hardware/audio/core/BnModule.h>
#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BnStreamOut.h>
#include <aidl/android/media/audio/BnHalAdapterVendorExtension.h>
#include <aidl/android/media/audio/common/AudioGainMode.h>
#include <aidl/android/media/audio/common/Int.h>
@@ -64,13 +66,13 @@
const std::vector<VendorParameter>& getSyncParameters() const { return mSyncParameters; }
protected:
- ndk::ScopedAStatus getVendorParametersImpl(const std::vector<std::string>& in_parameterIds) {
+ ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds) {
mGetParameterIds.insert(mGetParameterIds.end(), in_parameterIds.begin(),
in_parameterIds.end());
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus setVendorParametersImpl(const std::vector<VendorParameter>& in_parameters,
- bool async) {
+ ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+ bool async) {
if (async) {
mAsyncParameters.insert(mAsyncParameters.end(), in_parameters.begin(),
in_parameters.end());
@@ -187,6 +189,11 @@
speakerOutDevice.profiles = standardPcmAudioProfiles;
c.ports.push_back(speakerOutDevice);
+ AudioPort primaryOutMix =
+ createPort(c.nextPortId++, "primary output", 0, false, createPortMixExt(1, 1));
+ primaryOutMix.profiles = standardPcmAudioProfiles;
+ c.ports.push_back(primaryOutMix);
+
AudioPort btOutDevice =
createPort(c.nextPortId++, "BT A2DP Out", 0, false,
createPortDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
@@ -200,11 +207,141 @@
c.ports.push_back(btOutMix);
c.routes.push_back(createRoute({micInDevice, micInBackDevice}, primaryInMix));
+ c.routes.push_back(createRoute({primaryOutMix}, speakerOutDevice));
c.routes.push_back(createRoute({btOutMix}, btOutDevice));
return c;
}
+class StreamCommonMock : public ::aidl::android::hardware::audio::core::BnStreamCommon,
+ public VendorParameterMock {
+ ndk::ScopedAStatus close() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus prepareToClose() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus updateHwAvSyncId(int32_t) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
+ std::vector<VendorParameter>*) override {
+ return VendorParameterMock::getVendorParameters(in_parameterIds);
+ }
+ ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+ bool async) override {
+ return VendorParameterMock::setVendorParameters(in_parameters, async);
+ }
+ ndk::ScopedAStatus addEffect(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus removeEffect(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+class StreamContext {
+ public:
+ using Descriptor = ::aidl::android::hardware::audio::core::StreamDescriptor;
+ typedef ::android::AidlMessageQueue<
+ Descriptor::Command, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ CommandMQ;
+ typedef ::android::AidlMessageQueue<
+ Descriptor::Reply, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ ReplyMQ;
+ typedef ::android::AidlMessageQueue<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ DataMQ;
+
+ StreamContext() = default;
+ StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ,
+ std::unique_ptr<DataMQ> dataMQ)
+ : mCommandMQ(std::move(commandMQ)),
+ mReplyMQ(std::move(replyMQ)),
+ mDataMQ(std::move(dataMQ)) {}
+ void fillDescriptor(Descriptor* desc) {
+ if (mCommandMQ) {
+ desc->command = mCommandMQ->dupeDesc();
+ }
+ if (mReplyMQ) {
+ desc->reply = mReplyMQ->dupeDesc();
+ }
+ if (mDataMQ) {
+ desc->frameSizeBytes = 2;
+ desc->bufferSizeFrames = 48;
+ desc->audio.set<Descriptor::AudioBuffer::Tag::fmq>(mDataMQ->dupeDesc());
+ }
+ }
+
+ private:
+ std::unique_ptr<CommandMQ> mCommandMQ =
+ std::make_unique<CommandMQ>(1, true /*configureEventFlagWord*/);
+ std::unique_ptr<ReplyMQ> mReplyMQ =
+ std::make_unique<ReplyMQ>(1, true /*configureEventFlagWord*/);
+ std::unique_ptr<DataMQ> mDataMQ = std::make_unique<DataMQ>(96);
+};
+
+class StreamOutMock : public ::aidl::android::hardware::audio::core::BnStreamOut {
+ public:
+ explicit StreamOutMock(StreamContext&& ctx) : mContext(std::move(ctx)) {}
+
+ private:
+ ndk::ScopedAStatus getStreamCommon(
+ std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>* _aidl_return)
+ override {
+ if (!mCommon) {
+ mCommon = ndk::SharedRefBase::make<StreamCommonMock>();
+ }
+ *_aidl_return = mCommon;
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus updateMetadata(
+ const ::aidl::android::hardware::audio::common::SourceMetadata&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus updateOffloadMetadata(
+ const ::aidl::android::hardware::audio::common::AudioOffloadMetadata&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getHwVolume(std::vector<float>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setHwVolume(const std::vector<float>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioDescriptionMixLevel(float*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setAudioDescriptionMixLevel(float) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getDualMonoMode(
+ ::aidl::android::media::audio::common::AudioDualMonoMode*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setDualMonoMode(
+ ::aidl::android::media::audio::common::AudioDualMonoMode) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getRecommendedLatencyModes(
+ std::vector<::aidl::android::media::audio::common::AudioLatencyMode>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setLatencyMode(
+ ::aidl::android::media::audio::common::AudioLatencyMode) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getPlaybackRateParameters(
+ ::aidl::android::media::audio::common::AudioPlaybackRate*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setPlaybackRateParameters(
+ const ::aidl::android::media::audio::common::AudioPlaybackRate&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus selectPresentation(int32_t, int32_t) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ StreamContext mContext;
+ std::shared_ptr<StreamCommonMock> mCommon;
+};
+
class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule,
public VendorParameterMock {
public:
@@ -339,7 +476,10 @@
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus openOutputStream(const OpenOutputStreamArguments&,
- OpenOutputStreamReturn*) override {
+ OpenOutputStreamReturn* _aidl_return) override {
+ StreamContext context;
+ context.fillDescriptor(&_aidl_return->desc);
+ _aidl_return->stream = ndk::SharedRefBase::make<StreamOutMock>(std::move(context));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus getSupportedPlaybackRateFactors(SupportedPlaybackRateFactors*) override {
@@ -351,6 +491,7 @@
if (requested.id == 0) {
*patch = requested;
patch->id = mConfig.nextPatchId++;
+ patch->latenciesMs.push_back(100);
mConfig.patches.push_back(*patch);
ALOGD("%s: returning %s", __func__, patch->toString().c_str());
} else {
@@ -437,11 +578,11 @@
ndk::ScopedAStatus generateHwAvSyncId(int32_t*) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
std::vector<VendorParameter>*) override {
- return getVendorParametersImpl(in_parameterIds);
+ return VendorParameterMock::getVendorParameters(in_parameterIds);
}
ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
bool async) override {
- return setVendorParametersImpl(in_parameters, async);
+ return VendorParameterMock::setVendorParameters(in_parameters, async);
}
ndk::ScopedAStatus addDeviceEffect(
int32_t,
@@ -474,29 +615,6 @@
ScreenRotation mScreenRotation = ScreenRotation::DEG_0;
};
-class StreamCommonMock : public ::aidl::android::hardware::audio::core::BnStreamCommon,
- public VendorParameterMock {
- ndk::ScopedAStatus close() override { return ndk::ScopedAStatus::ok(); }
- ndk::ScopedAStatus prepareToClose() override { return ndk::ScopedAStatus::ok(); }
- ndk::ScopedAStatus updateHwAvSyncId(int32_t) override { return ndk::ScopedAStatus::ok(); }
- ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
- std::vector<VendorParameter>*) override {
- return getVendorParametersImpl(in_parameterIds);
- }
- ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
- bool async) override {
- return setVendorParametersImpl(in_parameters, async);
- }
- ndk::ScopedAStatus addEffect(
- const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
- return ndk::ScopedAStatus::ok();
- }
- ndk::ScopedAStatus removeEffect(
- const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
- return ndk::ScopedAStatus::ok();
- }
-};
-
VendorParameter makeVendorParameter(const std::string& id, int value) {
VendorParameter result{.id = id};
// Note: in real life, a parcelable type defined by vendor must be used,
@@ -708,7 +826,7 @@
class DeviceHalAidlTest : public testing::Test {
public:
void SetUp() override {
- mModule = ndk::SharedRefBase::make<ModuleMock>();
+ mModule = ndk::SharedRefBase::make<ModuleMock>(getTestConfiguration());
mDevice = sp<DeviceHalAidl>::make("test", mModule, nullptr /*vext*/);
}
void TearDown() override {
@@ -750,6 +868,46 @@
EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
}
+// See http://b/357487484#comment6
+TEST_F(DeviceHalAidlTest, StreamReleaseOnMapperCleanup) {
+ ASSERT_EQ(OK, mDevice->initCheck());
+ // Since the test is in effect probabilistic, try multiple times.
+ for (int i = 0; i < 100; ++i) {
+ sp<StreamOutHalInterface> stream1;
+ struct audio_config config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = 48000;
+ config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ config.format = AUDIO_FORMAT_PCM_16_BIT;
+ ASSERT_EQ(OK, mDevice->openOutputStream(42 /*handle*/, AUDIO_DEVICE_OUT_SPEAKER,
+ AUDIO_OUTPUT_FLAG_NONE, &config, "" /*address*/,
+ &stream1));
+ ASSERT_EQ(1, stream1->getStrongCount());
+ std::atomic<bool> stopReleaser = false;
+ // Try to catch the moment when Hal2AidlMapper promotes its wp<StreamHalInterface> to sp<>
+ // in Hal2AidlMapper::resetUnusedPatchesAndPortConfigs and release on our side in order to
+ // make Hal2AidlMapper the sole owner via a temporary sp and enforce destruction of the
+ // stream while the DeviceHalAidl::mLock is held.
+ std::thread releaser([&stream1, &stopReleaser]() {
+ while (!stopReleaser) {
+ if (stream1->getStrongCount() > 1) {
+ stream1.clear();
+ break;
+ }
+ std::this_thread::yield();
+ }
+ });
+ sp<StreamOutHalInterface> stream2;
+ // Opening another stream triggers a call to
+ // Hal2AidlMapper::resetUnusedPatchesAndPortConfigs. It must not cause a deadlock of the
+ // test (main) thread.
+ ASSERT_EQ(OK, mDevice->openOutputStream(43 /*handle*/, AUDIO_DEVICE_OUT_SPEAKER,
+ AUDIO_OUTPUT_FLAG_NONE, &config, "" /*address*/,
+ &stream2));
+ stopReleaser = true;
+ releaser.join();
+ }
+}
+
class DeviceHalAidlVendorParametersTest : public testing::Test {
public:
void SetUp() override {
diff --git a/media/libeffects/downmix/aidl/DownmixContext.cpp b/media/libeffects/downmix/aidl/DownmixContext.cpp
index 593e16f..3a55361 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.cpp
+++ b/media/libeffects/downmix/aidl/DownmixContext.cpp
@@ -100,11 +100,6 @@
return RetCode::SUCCESS;
}
-void DownmixContext::reset() {
- disable();
- resetBuffer();
-}
-
IEffect::Status DownmixContext::downmixProcess(float* in, float* out, int samples) {
IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
diff --git a/media/libeffects/downmix/aidl/DownmixContext.h b/media/libeffects/downmix/aidl/DownmixContext.h
index a381d7f..1be1508 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.h
+++ b/media/libeffects/downmix/aidl/DownmixContext.h
@@ -32,9 +32,8 @@
public:
DownmixContext(int statusDepth, const Parameter::Common& common);
~DownmixContext();
- RetCode enable();
- RetCode disable();
- void reset();
+ RetCode enable() override;
+ RetCode disable() override;
RetCode setDmType(Downmix::Type type) {
mType = type;
diff --git a/media/libeffects/downmix/aidl/EffectDownmix.cpp b/media/libeffects/downmix/aidl/EffectDownmix.cpp
index 883d41d..10c7c4f 100644
--- a/media/libeffects/downmix/aidl/EffectDownmix.cpp
+++ b/media/libeffects/downmix/aidl/EffectDownmix.cpp
@@ -71,26 +71,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus DownmixImpl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->reset();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus DownmixImpl::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::downmix != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
diff --git a/media/libeffects/downmix/aidl/EffectDownmix.h b/media/libeffects/downmix/aidl/EffectDownmix.h
index b7d621a..cea6d1b 100644
--- a/media/libeffects/downmix/aidl/EffectDownmix.h
+++ b/media/libeffects/downmix/aidl/EffectDownmix.h
@@ -31,7 +31,6 @@
DownmixImpl() = default;
~DownmixImpl() { cleanUp(); }
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
index 836e034..8324473 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
@@ -244,27 +244,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus DynamicsProcessingImpl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- return ndk::ScopedAStatus::ok();
- case CommandId::STOP:
- mContext->disable();
- return ndk::ScopedAStatus::ok();
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- return ndk::ScopedAStatus::ok();
- default:
- // Need this default handling for vendor extendable CommandId::VENDOR_COMMAND_*
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
-}
-
bool DynamicsProcessingImpl::isParamInRange(const Parameter::Specific& specific) {
auto& dp = specific.get<Parameter::Specific::dynamicsProcessing>();
return DynamicsProcessingRanges::isParamInRange(dp, kRanges);
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
index e850ba4..b34cdcf 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
@@ -36,7 +36,6 @@
ndk::ScopedAStatus open(const Parameter::Common& common,
const std::optional<Parameter::Specific>& specific,
OpenEffectReturn* ret) override;
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
index ada301b..fd4e615 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -48,10 +48,11 @@
return RetCode::SUCCESS;
}
-void DynamicsProcessingContext::reset() {
+RetCode DynamicsProcessingContext::reset() {
if (mDpFreq != nullptr) {
- mDpFreq.reset();
+ mDpFreq->reset();
}
+ return RetCode::SUCCESS;
}
RetCode DynamicsProcessingContext::setCommon(const Parameter::Common& common) {
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h
index ce657db..15c6811 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h
@@ -37,9 +37,9 @@
public:
DynamicsProcessingContext(int statusDepth, const Parameter::Common& common);
~DynamicsProcessingContext() = default;
- RetCode enable();
- RetCode disable();
- void reset();
+ RetCode enable() override;
+ RetCode disable() override;
+ RetCode reset() override;
// override EffectContext::setCommon to update mChannelCount
RetCode setCommon(const Parameter::Common& common) override;
diff --git a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp
index b803ee4..55e07fb 100644
--- a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp
+++ b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp
@@ -70,26 +70,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus HapticGeneratorImpl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->reset();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus HapticGeneratorImpl::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::hapticGenerator != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
diff --git a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h
index a775f06..8bae024 100644
--- a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h
+++ b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h
@@ -30,7 +30,6 @@
HapticGeneratorImpl() = default;
~HapticGeneratorImpl() { cleanUp(); }
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
index 9b2f443..e040fec 100644
--- a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
@@ -71,7 +71,7 @@
return RetCode::SUCCESS;
}
-void HapticGeneratorContext::reset() {
+RetCode HapticGeneratorContext::reset() {
for (auto& filter : mProcessorsRecord.filters) {
filter->clear();
}
@@ -81,6 +81,7 @@
for (auto& distortion : mProcessorsRecord.distortions) {
distortion->clear();
}
+ return RetCode::SUCCESS;
}
RetCode HapticGeneratorContext::setHgHapticScales(
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h
index 8a736e3..cf38e47 100644
--- a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h
@@ -65,9 +65,9 @@
public:
HapticGeneratorContext(int statusDepth, const Parameter::Common& common);
~HapticGeneratorContext();
- RetCode enable();
- RetCode disable();
- void reset();
+ RetCode enable() override;
+ RetCode disable() override;
+ RetCode reset() override;
RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales);
std::vector<HapticGenerator::HapticScale> getHgHapticScales() const;
diff --git a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp
index f89606e..592fd60 100644
--- a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp
+++ b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp
@@ -70,27 +70,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus LoudnessEnhancerImpl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus LoudnessEnhancerImpl::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::loudnessEnhancer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
diff --git a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h
index 98bdc6b..1e050f3 100644
--- a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h
+++ b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h
@@ -30,7 +30,6 @@
LoudnessEnhancerImpl() = default;
~LoudnessEnhancerImpl() { cleanUp(); }
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
diff --git a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp
index d8bcfc0..ac8b14a 100644
--- a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp
+++ b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp
@@ -43,17 +43,13 @@
return RetCode::SUCCESS;
}
-void LoudnessEnhancerContext::reset() {
- float targetAmp = pow(10, mGain / 2000.0f); // mB to linear amplification
+RetCode LoudnessEnhancerContext::setLeGain(int gainMb) {
+ float targetAmp = pow(10, gainMb / 2000.0f); // mB to linear amplification
if (mCompressor != nullptr) {
// Get samplingRate from input
mCompressor->Initialize(targetAmp, mCommon.input.base.sampleRate);
}
-}
-
-RetCode LoudnessEnhancerContext::setLeGain(int gainMb) {
mGain = gainMb;
- reset(); // apply parameter update
return RetCode::SUCCESS;
}
diff --git a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h
index 192b212..67ccd24 100644
--- a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h
+++ b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h
@@ -34,9 +34,8 @@
LoudnessEnhancerContext(int statusDepth, const Parameter::Common& common);
~LoudnessEnhancerContext() = default;
- RetCode enable();
- RetCode disable();
- void reset();
+ RetCode enable() override;
+ RetCode disable() override;
RetCode setLeGain(int gainMb);
int getLeGain() const { return mGain; }
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index 044c8dd..e5ab40d 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -35,9 +35,9 @@
void deInit();
lvm::BundleEffectType getBundleType() const { return mType; }
- RetCode enable();
+ RetCode enable() override;
RetCode enableOperatingMode();
- RetCode disable();
+ RetCode disable() override;
RetCode disableOperatingMode();
bool isDeviceSupportedBassBoost(
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
index 70c276d..2a81673 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -428,27 +428,6 @@
return RetCode::SUCCESS;
}
-ndk::ScopedAStatus EffectBundleAidl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
// Processing method running in EffectWorker thread.
IEffect::Status EffectBundleAidl::effectProcessImpl(float* in, float* out, int sampleToProcess) {
IEffect::Status status = {EX_NULL_POINTER, 0, 0};
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
index 429e941..479579b 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
@@ -49,8 +49,6 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
-
std::string getEffectName() override { return *mEffectName; }
private:
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
index 4d369b1..201c659 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -361,27 +361,6 @@
return RetCode::SUCCESS;
}
-ndk::ScopedAStatus EffectReverb::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
// Processing method running in EffectWorker thread.
IEffect::Status EffectReverb::effectProcessImpl(float* in, float* out, int sampleToProcess) {
IEffect::Status status = {EX_NULL_POINTER, 0, 0};
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
index e0771a1..4acac1d 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
@@ -42,8 +42,6 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
-
std::string getEffectName() override { return *mEffectName; }
private:
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
index 44391f2..f55eac5 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -51,8 +51,8 @@
RetCode init();
void deInit();
- RetCode enable();
- RetCode disable();
+ RetCode enable() override;
+ RetCode disable() override;
bool isAuxiliary();
bool isPreset();
diff --git a/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp b/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp
index 87d267b..4bc34e7 100644
--- a/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp
+++ b/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp
@@ -417,27 +417,6 @@
return RetCode::SUCCESS;
}
-ndk::ScopedAStatus EffectPreProcessing::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
// Processing method running in EffectWorker thread.
IEffect::Status EffectPreProcessing::effectProcessImpl(float* in, float* out, int sampleToProcess) {
IEffect::Status status = {EX_NULL_POINTER, 0, 0};
diff --git a/media/libeffects/preprocessing/aidl/EffectPreProcessing.h b/media/libeffects/preprocessing/aidl/EffectPreProcessing.h
index 9ce5597..31f5737 100644
--- a/media/libeffects/preprocessing/aidl/EffectPreProcessing.h
+++ b/media/libeffects/preprocessing/aidl/EffectPreProcessing.h
@@ -43,8 +43,6 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) override;
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
-
std::string getEffectName() override { return *mEffectName; }
private:
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingContext.h b/media/libeffects/preprocessing/aidl/PreProcessingContext.h
index 11a2bea..1b9b77b 100644
--- a/media/libeffects/preprocessing/aidl/PreProcessingContext.h
+++ b/media/libeffects/preprocessing/aidl/PreProcessingContext.h
@@ -45,8 +45,8 @@
PreProcessingEffectType getPreProcessingType() const { return mType; }
- RetCode enable();
- RetCode disable();
+ RetCode enable() override;
+ RetCode disable() override;
RetCode setCommon(const Parameter::Common& common) override;
void updateConfigs(const Parameter::Common& common);
diff --git a/media/libeffects/visualizer/aidl/Visualizer.cpp b/media/libeffects/visualizer/aidl/Visualizer.cpp
index 9b493d4..f4b9b25 100644
--- a/media/libeffects/visualizer/aidl/Visualizer.cpp
+++ b/media/libeffects/visualizer/aidl/Visualizer.cpp
@@ -85,27 +85,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus VisualizerImpl::commandImpl(CommandId command) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- switch (command) {
- case CommandId::START:
- mContext->enable();
- break;
- case CommandId::STOP:
- mContext->disable();
- break;
- case CommandId::RESET:
- mContext->disable();
- mContext->resetBuffer();
- break;
- default:
- LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "commandIdNotSupported");
- }
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus VisualizerImpl::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
@@ -222,6 +201,7 @@
RetCode VisualizerImpl::releaseContext() {
if (mContext) {
mContext->disable();
+ mContext->reset();
mContext->resetBuffer();
}
return RetCode::SUCCESS;
diff --git a/media/libeffects/visualizer/aidl/Visualizer.h b/media/libeffects/visualizer/aidl/Visualizer.h
index 3180972..f25b78d 100644
--- a/media/libeffects/visualizer/aidl/Visualizer.h
+++ b/media/libeffects/visualizer/aidl/Visualizer.h
@@ -32,7 +32,6 @@
VisualizerImpl() = default;
~VisualizerImpl() { cleanUp(); }
- ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
REQUIRES(mImplMutex) override;
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.cpp b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
index 1e08674..a368e52 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.cpp
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
@@ -57,7 +57,7 @@
#endif
mChannelCount = channelCount;
mCommon = common;
- std::fill(mCaptureBuf.begin(), mCaptureBuf.end(), 0x80);
+ reset();
return RetCode::SUCCESS;
}
@@ -77,8 +77,9 @@
return RetCode::SUCCESS;
}
-void VisualizerContext::reset() {
+RetCode VisualizerContext::reset() {
std::fill(mCaptureBuf.begin(), mCaptureBuf.end(), 0x80);
+ return RetCode::SUCCESS;
}
RetCode VisualizerContext::setCaptureSamples(int samples) {
@@ -109,7 +110,6 @@
mDownstreamLatency = latency;
return RetCode::SUCCESS;
}
-
int VisualizerContext::getDownstreamLatency() {
return mDownstreamLatency;
}
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.h b/media/libeffects/visualizer/aidl/VisualizerContext.h
index 9715e20..d4abbd3 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.h
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.h
@@ -36,10 +36,10 @@
RetCode initParams(const Parameter::Common& common);
- RetCode enable();
- RetCode disable();
+ RetCode enable() override;
+ RetCode disable() override;
// keep all parameters and reset buffer.
- void reset();
+ RetCode reset() override;
RetCode setCaptureSamples(int32_t captureSize);
int32_t getCaptureSamples();
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index d4b4b6c..8a962c6 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -255,6 +255,45 @@
}
cc_library_shared {
+ name: "libmedia_codeclist_capabilities",
+
+ srcs: [
+ "AudioCapabilities.cpp",
+ "CodecCapabilities.cpp",
+ "CodecCapabilitiesUtils.cpp",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ "-Wall",
+ ],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+}
+
+cc_library_shared {
name: "libmedia_codeclist",
srcs: [
@@ -270,6 +309,7 @@
"android.hardware.media.omx@1.0",
"libbinder",
"liblog",
+ "libmedia_codeclist_capabilities",
"libstagefright_foundation",
"libutils",
],
diff --git a/media/libmedia/AudioCapabilities.cpp b/media/libmedia/AudioCapabilities.cpp
new file mode 100644
index 0000000..e8cf517
--- /dev/null
+++ b/media/libmedia/AudioCapabilities.cpp
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2024, 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 "AudioCapabilities"
+
+#include <android-base/strings.h>
+#include <android-base/properties.h>
+
+#include <media/AudioCapabilities.h>
+#include <media/CodecCapabilities.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+namespace android {
+
+const Range<int>& AudioCapabilities::getBitrateRange() const {
+ return mBitrateRange;
+}
+
+const std::vector<int>& AudioCapabilities::getSupportedSampleRates() const {
+ return mSampleRates;
+}
+
+const std::vector<Range<int>>&
+ AudioCapabilities::getSupportedSampleRateRanges() const {
+ return mSampleRateRanges;
+}
+
+int AudioCapabilities::getMaxInputChannelCount() const {
+ int overallMax = 0;
+ for (int i = mInputChannelRanges.size() - 1; i >= 0; i--) {
+ int lmax = mInputChannelRanges[i].upper();
+ if (lmax > overallMax) {
+ overallMax = lmax;
+ }
+ }
+ return overallMax;
+}
+
+int AudioCapabilities::getMinInputChannelCount() const {
+ int overallMin = MAX_INPUT_CHANNEL_COUNT;
+ for (int i = mInputChannelRanges.size() - 1; i >= 0; i--) {
+ int lmin = mInputChannelRanges[i].lower();
+ if (lmin < overallMin) {
+ overallMin = lmin;
+ }
+ }
+ return overallMin;
+}
+
+const std::vector<Range<int>>&
+ AudioCapabilities::getInputChannelCountRanges() const {
+ return mInputChannelRanges;
+}
+
+// static
+std::shared_ptr<AudioCapabilities> AudioCapabilities::Create(std::string mediaType,
+ std::vector<ProfileLevel> profLevs, const sp<AMessage> &format) {
+ std::shared_ptr<AudioCapabilities> caps(new AudioCapabilities());
+ caps->init(mediaType, profLevs, format);
+ return caps;
+}
+
+void AudioCapabilities::init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+ const sp<AMessage> &format) {
+ mMediaType = mediaType;
+ mProfileLevels = profLevs;
+ mError = 0;
+
+ initWithPlatformLimits();
+ applyLevelLimits();
+ parseFromInfo(format);
+}
+
+void AudioCapabilities::initWithPlatformLimits() {
+ mBitrateRange = Range<int>(0, INT_MAX);
+ mInputChannelRanges.push_back(Range<int>(1, MAX_INPUT_CHANNEL_COUNT));
+
+ const int minSampleRate = base::GetIntProperty("ro.mediacodec.min_sample_rate", 7350);
+ const int maxSampleRate = base::GetIntProperty("ro.mediacodec.max_sample_rate", 192000);
+ mSampleRateRanges.push_back(Range<int>(minSampleRate, maxSampleRate));
+}
+
+bool AudioCapabilities::supports(int sampleRate, int inputChannels) {
+ // channels and sample rates are checked orthogonally
+ if (inputChannels != 0
+ && !std::any_of(mInputChannelRanges.begin(), mInputChannelRanges.end(),
+ [inputChannels](const Range<int> &a) { return a.contains(inputChannels); })) {
+ return false;
+ }
+ if (sampleRate != 0
+ && !std::any_of(mSampleRateRanges.begin(), mSampleRateRanges.end(),
+ [sampleRate](const Range<int> &a) { return a.contains(sampleRate); })) {
+ return false;
+ }
+ return true;
+}
+
+bool AudioCapabilities::isSampleRateSupported(int sampleRate) {
+ return supports(sampleRate, 0);
+}
+
+void AudioCapabilities::limitSampleRates(std::vector<int> rates) {
+ std::vector<Range<int>> sampleRateRanges;
+ std::sort(rates.begin(), rates.end());
+ for (int rate : rates) {
+ if (supports(rate, 0 /* channels */)) {
+ sampleRateRanges.push_back(Range<int>(rate, rate));
+ }
+ }
+ mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, sampleRateRanges);
+ createDiscreteSampleRates();
+}
+
+void AudioCapabilities::createDiscreteSampleRates() {
+ mSampleRates.clear();
+ for (int i = 0; i < mSampleRateRanges.size(); i++) {
+ mSampleRates.push_back(mSampleRateRanges[i].lower());
+ }
+}
+
+void AudioCapabilities::limitSampleRates(std::vector<Range<int>> rateRanges) {
+ sortDistinctRanges(&rateRanges);
+ mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
+ // check if all values are discrete
+ for (Range<int> range: mSampleRateRanges) {
+ if (range.lower() != range.upper()) {
+ mSampleRates.clear();
+ return;
+ }
+ }
+ createDiscreteSampleRates();
+}
+
+void AudioCapabilities::applyLevelLimits() {
+ std::vector<int> sampleRates;
+ std::optional<Range<int>> sampleRateRange;
+ std::optional<Range<int>> bitRates;
+ int maxChannels = MAX_INPUT_CHANNEL_COUNT;
+
+ // const char *mediaType = mMediaType.c_str();
+ if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MPEG)) {
+ sampleRates = {
+ 8000, 11025, 12000,
+ 16000, 22050, 24000,
+ 32000, 44100, 48000 };
+ bitRates = Range<int>(8000, 320000);
+ maxChannels = 2;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_NB)) {
+ sampleRates = { 8000 };
+ bitRates = Range<int>(4750, 12200);
+ maxChannels = 1;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_WB)) {
+ sampleRates = { 16000 };
+ bitRates = Range<int>(6600, 23850);
+ maxChannels = 1;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
+ sampleRates = {
+ 7350, 8000,
+ 11025, 12000, 16000,
+ 22050, 24000, 32000,
+ 44100, 48000, 64000,
+ 88200, 96000 };
+ bitRates = Range<int>(8000, 510000);
+ maxChannels = 48;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_VORBIS)) {
+ bitRates = Range<int>(32000, 500000);
+ sampleRateRange = Range<int>(8000, 192000);
+ maxChannels = 255;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_OPUS)) {
+ bitRates = Range<int>(6000, 510000);
+ sampleRates = { 8000, 12000, 16000, 24000, 48000 };
+ maxChannels = 255;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_RAW)) {
+ sampleRateRange = Range<int>(1, 192000);
+ bitRates = Range<int>(1, 10000000);
+ maxChannels = MAX_NUM_CHANNELS;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_FLAC)) {
+ sampleRateRange = Range<int>(1, 655350);
+ // lossless codec, so bitrate is ignored
+ maxChannels = 255;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_ALAW)
+ || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_MLAW)) {
+ sampleRates = { 8000 };
+ bitRates = Range<int>(64000, 64000);
+ // platform allows multiple channels for this format
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MSGSM)) {
+ sampleRates = { 8000 };
+ bitRates = Range<int>(13000, 13000);
+ maxChannels = 1;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC3)) {
+ maxChannels = 6;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3)) {
+ maxChannels = 16;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3_JOC)) {
+ sampleRates = { 48000 };
+ bitRates = Range<int>(32000, 6144000);
+ maxChannels = 16;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC4)) {
+ sampleRates = { 44100, 48000, 96000, 192000 };
+ bitRates = Range<int>(16000, 2688000);
+ maxChannels = 24;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS)) {
+ sampleRates = { 44100, 48000 };
+ bitRates = Range<int>(96000, 1524000);
+ maxChannels = 6;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_HD)) {
+ for (ProfileLevel profileLevel: mProfileLevels) {
+ switch (profileLevel.mProfile) {
+ case DTS_HDProfileLBR:
+ sampleRates = { 22050, 24000, 44100, 48000 };
+ bitRates = Range<int>(32000, 768000);
+ break;
+ case DTS_HDProfileHRA:
+ case DTS_HDProfileMA:
+ sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
+ bitRates = Range<int>(96000, 24500000);
+ break;
+ default:
+ ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
+ mMediaType.c_str());
+ mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
+ sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
+ bitRates = Range<int>(96000, 24500000);
+ }
+ }
+ maxChannels = 8;
+ } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_UHD)) {
+ for (ProfileLevel profileLevel: mProfileLevels) {
+ switch (profileLevel.mProfile) {
+ case DTS_UHDProfileP2:
+ sampleRates = { 48000 };
+ bitRates = Range<int>(96000, 768000);
+ maxChannels = 10;
+ break;
+ case DTS_UHDProfileP1:
+ sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
+ bitRates = Range<int>(96000, 24500000);
+ maxChannels = 32;
+ break;
+ default:
+ ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
+ mMediaType.c_str());
+ mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
+ sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
+ bitRates = Range<int>(96000, 24500000);
+ maxChannels = 32;
+ }
+ }
+ } else {
+ ALOGW("Unsupported mediaType %s", mMediaType.c_str());
+ mError |= ERROR_CAPABILITIES_UNSUPPORTED;
+ }
+
+ // restrict ranges
+ if (!sampleRates.empty()) {
+ limitSampleRates(sampleRates);
+ } else if (sampleRateRange) {
+ std::vector<Range<int>> rateRanges = { sampleRateRange.value() };
+ limitSampleRates(rateRanges);
+ }
+
+ Range<int> channelRange = Range<int>(1, maxChannels);
+ std::vector<Range<int>> inputChannels = { channelRange };
+ applyLimits(inputChannels, bitRates);
+}
+
+void AudioCapabilities::applyLimits(
+ const std::vector<Range<int>> &inputChannels,
+ const std::optional<Range<int>> &bitRates) {
+ // clamp & make a local copy
+ std::vector<Range<int>> inputChannelsCopy(inputChannels.size());
+ for (int i = 0; i < inputChannels.size(); i++) {
+ int lower = inputChannels[i].clamp(1);
+ int upper = inputChannels[i].clamp(MAX_INPUT_CHANNEL_COUNT);
+ inputChannelsCopy[i] = Range<int>(lower, upper);
+ }
+
+ // sort, intersect with existing, & save channel list
+ sortDistinctRanges(&inputChannelsCopy);
+ mInputChannelRanges = intersectSortedDistinctRanges(inputChannelsCopy, mInputChannelRanges);
+
+ if (bitRates) {
+ mBitrateRange = mBitrateRange.intersect(bitRates.value());
+ }
+}
+
+void AudioCapabilities::parseFromInfo(const sp<AMessage> &format) {
+ int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
+ std::vector<Range<int>> channels = { Range<int>(1, maxInputChannels) };
+ std::optional<Range<int>> bitRates = POSITIVE_INTEGERS;
+
+ AString rateAString;
+ if (format->findString("sample-rate-ranges", &rateAString)) {
+ std::vector<std::string> rateStrings = base::Split(std::string(rateAString.c_str()), ",");
+ std::vector<Range<int>> rateRanges;
+ for (std::string rateString : rateStrings) {
+ std::optional<Range<int>> rateRange = ParseIntRange(rateString);
+ if (!rateRange) {
+ continue;
+ }
+ rateRanges.push_back(rateRange.value());
+ }
+ limitSampleRates(rateRanges);
+ }
+
+ // we will prefer channel-ranges over max-channel-count
+ AString valueStr;
+ if (format->findString("channel-ranges", &valueStr)) {
+ std::vector<std::string> channelStrings = base::Split(std::string(valueStr.c_str()), ",");
+ std::vector<Range<int>> channelRanges;
+ for (std::string channelString : channelStrings) {
+ std::optional<Range<int>> channelRange = ParseIntRange(channelString);
+ if (!channelRange) {
+ continue;
+ }
+ channelRanges.push_back(channelRange.value());
+ }
+ channels = channelRanges;
+ } else if (format->findString("channel-range", &valueStr)) {
+ std::optional<Range<int>> oneRange = ParseIntRange(std::string(valueStr.c_str()));
+ if (oneRange) {
+ channels = { oneRange.value() };
+ }
+ } else if (format->findString("max-channel-count", &valueStr)) {
+ maxInputChannels = std::atoi(valueStr.c_str());
+ if (maxInputChannels == 0) {
+ channels = { Range<int>(0, 0) };
+ } else {
+ channels = { Range<int>(1, maxInputChannels) };
+ }
+ } else if ((mError & ERROR_CAPABILITIES_UNSUPPORTED) != 0) {
+ maxInputChannels = 0;
+ channels = { Range<int>(0, 0) };
+ }
+
+ if (format->findString("bitrate-range", &valueStr)) {
+ std::optional<Range<int>> parsedBitrate = ParseIntRange(valueStr.c_str());
+ if (parsedBitrate) {
+ bitRates = bitRates.value().intersect(parsedBitrate.value());
+ }
+ }
+
+ applyLimits(channels, bitRates);
+}
+
+void AudioCapabilities::getDefaultFormat(sp<AMessage> &format) {
+ // report settings that have only a single choice
+ if (mBitrateRange.lower() == mBitrateRange.upper()) {
+ format->setInt32(KEY_BIT_RATE, mBitrateRange.lower());
+ }
+ if (getMaxInputChannelCount() == 1) {
+ // mono-only format
+ format->setInt32(KEY_CHANNEL_COUNT, 1);
+ }
+ if (!mSampleRates.empty() && mSampleRates.size() == 1) {
+ format->setInt32(KEY_SAMPLE_RATE, mSampleRates[0]);
+ }
+}
+
+bool AudioCapabilities::supportsFormat(const sp<AMessage> &format) {
+ int32_t sampleRate;
+ format->findInt32(KEY_SAMPLE_RATE, &sampleRate);
+ int32_t channels;
+ format->findInt32(KEY_CHANNEL_COUNT, &channels);
+
+ if (!supports(sampleRate, channels)) {
+ return false;
+ }
+
+ if (!CodecCapabilities::SupportsBitrate(mBitrateRange, format)) {
+ return false;
+ }
+
+ // nothing to do for:
+ // KEY_CHANNEL_MASK: codecs don't get this
+ // KEY_IS_ADTS: required feature for all AAC decoders
+ return true;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/media/libmedia/CodecCapabilities.cpp b/media/libmedia/CodecCapabilities.cpp
new file mode 100644
index 0000000..5bed1c4
--- /dev/null
+++ b/media/libmedia/CodecCapabilities.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2024, 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 "CodecCapabilities"
+
+#include <utils/Log.h>
+#include <media/CodecCapabilities.h>
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+bool CodecCapabilities::SupportsBitrate(Range<int> bitrateRange,
+ const sp<AMessage> &format) {
+ // consider max bitrate over average bitrate for support
+ int32_t maxBitrate = 0;
+ format->findInt32(KEY_MAX_BIT_RATE, &maxBitrate);
+ int32_t bitrate = 0;
+ format->findInt32(KEY_BIT_RATE, &bitrate);
+
+ if (bitrate == 0) {
+ bitrate = maxBitrate;
+ } else if (maxBitrate != 0) {
+ bitrate = std::max(bitrate, maxBitrate);
+ }
+
+ if (bitrate > 0) {
+ return bitrateRange.contains(bitrate);
+ }
+
+ return true;
+}
+
+const std::string& CodecCapabilities::getMediaType() {
+ return mMediaType;
+}
+
+const std::vector<ProfileLevel>& CodecCapabilities::getProfileLevels() {
+ return mProfileLevels;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/media/libmedia/CodecCapabilitiesUtils.cpp b/media/libmedia/CodecCapabilitiesUtils.cpp
new file mode 100644
index 0000000..edfc9be
--- /dev/null
+++ b/media/libmedia/CodecCapabilitiesUtils.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 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 "CodecCapabilitiesUtils"
+#include <utils/Log.h>
+
+#include <algorithm>
+#include <cmath>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include <media/CodecCapabilitiesUtils.h>
+
+#include <media/stagefright/foundation/AUtils.h>
+
+namespace android {
+
+std::optional<Range<int>> ParseIntRange(const std::string &str) {
+ if (str.empty()) {
+ ALOGW("could not parse empty integer range");
+ return std::nullopt;
+ }
+ int lower, upper;
+ std::regex regex("([0-9]+)-([0-9]+)");
+ std::smatch match;
+ if (std::regex_match(str, match, regex)) {
+ lower = std::atoi(match[1].str().c_str());
+ upper = std::atoi(match[2].str().c_str());
+ } else if (std::atoi(str.c_str()) != 0) {
+ lower = upper = std::atoi(str.c_str());
+ } else {
+ ALOGW("could not parse integer range: %s", str.c_str());
+ return std::nullopt;
+ }
+ return std::make_optional<Range<int>>(lower, upper);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/media/libmedia/include/media/AudioCapabilities.h b/media/libmedia/include/media/AudioCapabilities.h
new file mode 100644
index 0000000..2bc3335
--- /dev/null
+++ b/media/libmedia/include/media/AudioCapabilities.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2024, 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 AUDIO_CAPABILITIES_H_
+
+#define AUDIO_CAPABILITIES_H_
+
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <system/audio.h>
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct AudioCapabilities {
+ /**
+ * Create AudioCapabilities.
+ */
+ static std::shared_ptr<AudioCapabilities> Create(std::string mediaType,
+ std::vector<ProfileLevel> profLevs, const sp<AMessage> &format);
+
+ /**
+ * Returns the range of supported bitrates in bits/second.
+ */
+ const Range<int>& getBitrateRange() const;
+
+ /**
+ * Returns the array of supported sample rates if the codec
+ * supports only discrete values. Otherwise, it returns an empty array.
+ * The array is sorted in ascending order.
+ */
+ const std::vector<int>& getSupportedSampleRates() const;
+
+ /**
+ * Returns the array of supported sample rate ranges. The
+ * array is sorted in ascending order, and the ranges are
+ * distinct.
+ */
+ const std::vector<Range<int>>& getSupportedSampleRateRanges() const;
+
+ /**
+ * Returns the maximum number of input channels supported.
+ * The returned value should be between 1 and 255.
+ *
+ * Through {@link android.os.Build.VERSION_CODES#R}, this method indicated support
+ * for any number of input channels between 1 and this maximum value.
+ *
+ * As of {@link android.os.Build.VERSION_CODES#S},
+ * the implied lower limit of 1 channel is no longer valid.
+ * As of {@link android.os.Build.VERSION_CODES#S}, {@link #getMaxInputChannelCount} is
+ * superseded by {@link #getInputChannelCountRanges},
+ * which returns an array of ranges of channels.
+ * The {@link #getMaxInputChannelCount} method will return the highest value
+ * in the ranges returned by {@link #getInputChannelCountRanges}
+ */
+ int getMaxInputChannelCount() const;
+
+ /**
+ * Returns the minimum number of input channels supported.
+ * This is often 1, but does vary for certain mime types.
+ *
+ * This returns the lowest channel count in the ranges returned by
+ * {@link #getInputChannelCountRanges}.
+ */
+ int getMinInputChannelCount() const;
+
+ /**
+ * Returns an array of ranges representing the number of input channels supported.
+ * The codec supports any number of input channels within this range.
+ *
+ * This supersedes the {@link #getMaxInputChannelCount} method.
+ *
+ * For many codecs, this will be a single range [1..N], for some N.
+ *
+ * The returned array cannot be empty.
+ */
+ const std::vector<Range<int>>& getInputChannelCountRanges() const;
+
+ /**
+ * Query whether the sample rate is supported by the codec.
+ */
+ bool isSampleRateSupported(int sampleRate);
+
+ /* For internal use only. Not exposed as a public API */
+ void getDefaultFormat(sp<AMessage> &format);
+
+ /* For internal use only. Not exposed as a public API */
+ bool supportsFormat(const sp<AMessage> &format);
+
+private:
+ static constexpr int MAX_INPUT_CHANNEL_COUNT = 30;
+ static constexpr uint32_t MAX_NUM_CHANNELS = FCC_LIMIT;
+
+ int mError;
+ std::string mMediaType;
+ std::vector<ProfileLevel> mProfileLevels;
+
+ Range<int> mBitrateRange;
+
+ std::vector<int> mSampleRates;
+ std::vector<Range<int>> mSampleRateRanges;
+ std::vector<Range<int>> mInputChannelRanges;
+
+ /* no public constructor */
+ AudioCapabilities() {}
+ void init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+ const sp<AMessage> &format);
+ void initWithPlatformLimits();
+ bool supports(int sampleRate, int inputChannels);
+ void limitSampleRates(std::vector<int> rates);
+ void createDiscreteSampleRates();
+ void limitSampleRates(std::vector<Range<int>> rateRanges);
+ void applyLevelLimits();
+ void applyLimits(const std::vector<Range<int>> &inputChannels,
+ const std::optional<Range<int>> &bitRates);
+ void parseFromInfo(const sp<AMessage> &format);
+
+ friend struct CodecCapabilities;
+};
+
+} // namespace android
+
+#endif // AUDIO_CAPABILITIES_H_
\ No newline at end of file
diff --git a/media/libmedia/include/media/CodecCapabilities.h b/media/libmedia/include/media/CodecCapabilities.h
new file mode 100644
index 0000000..9d1c4ea
--- /dev/null
+++ b/media/libmedia/include/media/CodecCapabilities.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024, 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 CODEC_CAPABILITIES_H_
+
+#define CODEC_CAPABILITIES_H_
+
+#include <media/AudioCapabilities.h>
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct CodecCapabilities {
+
+ static bool SupportsBitrate(Range<int> bitrateRange,
+ const sp<AMessage> &format);
+
+ /**
+ * Returns the media type for which this codec-capability object was created.
+ */
+ const std::string& getMediaType();
+
+ /**
+ * Returns the supported profile levels.
+ */
+ const std::vector<ProfileLevel>& getProfileLevels();
+
+private:
+ std::string mMediaType;
+ std::vector<ProfileLevel> mProfileLevels;
+
+ std::shared_ptr<AudioCapabilities> mAudioCaps;
+};
+
+} // namespace android
+
+#endif // CODEC_CAPABILITIES_H_
\ No newline at end of file
diff --git a/media/libmedia/include/media/CodecCapabilitiesUtils.h b/media/libmedia/include/media/CodecCapabilitiesUtils.h
new file mode 100644
index 0000000..2bf822a
--- /dev/null
+++ b/media/libmedia/include/media/CodecCapabilitiesUtils.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2024 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 CODEC_CAPABILITIES__UTILS_H_
+
+#define CODEC_CAPABILITIES__UTILS_H_
+
+#include <algorithm>
+#include <cmath>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/AUtils.h>
+
+namespace android {
+
+struct ProfileLevel {
+ uint32_t mProfile;
+ uint32_t mLevel;
+ bool operator <(const ProfileLevel &o) const {
+ return mProfile < o.mProfile || (mProfile == o.mProfile && mLevel < o.mLevel);
+ }
+};
+
+/**
+ * Immutable class for describing the range of two numeric values.
+ *
+ * To make it immutable, all data are private and all functions are const.
+ *
+ * From frameworks/base/core/java/android/util/Range.java
+ */
+template<typename T>
+struct Range {
+ Range() : lower_(), upper_() {}
+
+ Range(T l, T u) : lower_(l), upper_(u) {}
+
+ constexpr bool empty() const { return lower_ > upper_; }
+
+ T lower() const { return lower_; }
+
+ T upper() const { return upper_; }
+
+ // Check if a value is in the range.
+ bool contains(T value) const {
+ return lower_ <= value && upper_ >= value;
+ }
+
+ bool contains(Range<T> range) const {
+ return (range.lower_ >= lower_) && (range.upper_ <= upper_);
+ }
+
+ // Clamp a value in the range
+ T clamp(T value) const{
+ if (value < lower_) {
+ return lower_;
+ } else if (value > upper_) {
+ return upper_;
+ } else {
+ return value;
+ }
+ }
+
+ // Return the intersected range
+ Range<T> intersect(Range<T> range) const {
+ if (lower_ >= range.lower() && range.upper() >= upper_) {
+ // range includes this
+ return *this;
+ } else if (range.lower() >= lower_ && range.upper() <= upper_) {
+ // this includes range
+ return range;
+ } else {
+ // if ranges are disjoint returns an empty Range(lower > upper)
+ Range<T> result = Range<T>(std::max(lower_, range.lower_),
+ std::min(upper_, range.upper_));
+ if (result.empty()) {
+ ALOGE("Failed to intersect 2 ranges as they are disjoint");
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Returns the intersection of this range and the inclusive range
+ * specified by {@code [lower, upper]}.
+ * <p>
+ * See {@link #intersect(Range)} for more details.</p>
+ *
+ * @param lower a non-{@code null} {@code T} reference
+ * @param upper a non-{@code null} {@code T} reference
+ * @return the intersection of this range and the other range
+ *
+ * @throws NullPointerException if {@code lower} or {@code upper} was {@code null}
+ * @throws IllegalArgumentException if the ranges are disjoint.
+ */
+ Range<T> intersect(T lower, T upper) {
+ return Range(std::max(lower_, lower), std::min(upper_, upper));
+ }
+
+private:
+ T lower_;
+ T upper_;
+};
+
+static const Range<int> POSITIVE_INTEGERS = Range<int>(1, INT_MAX);
+
+// found stuff that is not supported by framework (=> this should not happen)
+constexpr int ERROR_CAPABILITIES_UNRECOGNIZED = (1 << 0);
+// found profile/level for which we don't have capability estimates
+constexpr int ERROR_CAPABILITIES_UNSUPPORTED = (1 << 1);
+// have not found any profile/level for which we don't have capability estimate
+// constexpr int ERROR_NONE_SUPPORTED = (1 << 2);
+
+/**
+ * Sorts distinct (non-intersecting) range array in ascending order.
+ * From frameworks/base/media/java/android/media/Utils.java
+ */
+template<typename T>
+void sortDistinctRanges(std::vector<Range<T>> *ranges) {
+ std::sort(ranges->begin(), ranges->end(),
+ [](Range<T> r1, Range<T> r2) {
+ if (r1.upper() < r2.lower()) {
+ return true;
+ } else if (r1.lower() > r2.upper()) {
+ return false;
+ } else {
+ ALOGE("sample rate ranges must be distinct.");
+ return false;
+ }
+ });
+}
+
+/**
+ * Returns the intersection of two sets of non-intersecting ranges
+ * From frameworks/base/media/java/android/media/Utils.java
+ * @param one a sorted set of non-intersecting ranges in ascending order
+ * @param another another sorted set of non-intersecting ranges in ascending order
+ * @return the intersection of the two sets, sorted in ascending order
+ */
+template<typename T>
+std::vector<Range<T>> intersectSortedDistinctRanges(
+ const std::vector<Range<T>> &one, const std::vector<Range<T>> &another) {
+ std::vector<Range<T>> result;
+ int ix = 0;
+ for (Range<T> range : another) {
+ while (ix < one.size() && one[ix].upper() < range.lower()) {
+ ++ix;
+ }
+ while (ix < one.size() && one[ix].upper() < range.upper()) {
+ result.push_back(range.intersect(one[ix]));
+ ++ix;
+ }
+ if (ix == one.size()) {
+ break;
+ }
+ if (one[ix].lower() <= range.upper()) {
+ result.push_back(range.intersect(one[ix]));
+ }
+ }
+ return result;
+}
+
+// parse string into int range
+std::optional<Range<int>> ParseIntRange(const std::string &str);
+
+} // namespace android
+
+#endif // CODEC_CAPABILITIES__UTILS_H_
\ No newline at end of file
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index 88a2dc4..72aca98 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -20,6 +20,8 @@
#include <android-base/macros.h>
#include <binder/Parcel.h>
+#include <media/CodecCapabilities.h>
+#include <media/CodecCapabilitiesUtils.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
@@ -43,13 +45,10 @@
struct MediaCodecListWriter;
struct MediaCodecInfo : public RefBase {
- struct ProfileLevel {
- uint32_t mProfile;
- uint32_t mLevel;
- bool operator <(const ProfileLevel &o) const {
- return mProfile < o.mProfile || (mProfile == o.mProfile && mLevel < o.mLevel);
- }
- };
+
+ // Moved to CodecCapabilitiesUtils.h
+ // Map MediaCodecInfo::ProfileLevel to android::ProfileLevel to maintain compatibility.
+ typedef ::android::ProfileLevel ProfileLevel;
struct CapabilitiesWriter;
diff --git a/media/libmedia/include/media/RingBuffer.h b/media/libmedia/include/media/RingBuffer.h
index 4d92d87..a08f35e 100644
--- a/media/libmedia/include/media/RingBuffer.h
+++ b/media/libmedia/include/media/RingBuffer.h
@@ -44,8 +44,14 @@
/**
* Forward iterator to this class. Implements an std:forward_iterator.
*/
- class iterator : public std::iterator<std::forward_iterator_tag, T> {
+ class iterator {
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = T;
+ using difference_type = std::ptrdiff_t;
+ using pointer = T*;
+ using reference = T&;
+
iterator(T* ptr, size_t size, size_t pos, size_t ctr);
iterator& operator++();
@@ -357,5 +363,3 @@
}; // namespace android
#endif // ANDROID_SERVICE_UTILS_RING_BUFFER_H
-
-
diff --git a/media/libmedia/tests/codeccapabilities/Android.bp b/media/libmedia/tests/codeccapabilities/Android.bp
new file mode 100644
index 0000000..79eb71a
--- /dev/null
+++ b/media/libmedia/tests/codeccapabilities/Android.bp
@@ -0,0 +1,36 @@
+cc_test {
+ name: "CodecCapabilitiesTest",
+ team: "trendy_team_media_codec_framework",
+
+ test_suites: [
+ "general-tests",
+ ],
+ gtest: true,
+
+ srcs: [
+ "CodecCapabilitiesTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libmedia_codeclist", // available >= R
+ "libmedia_codeclist_capabilities",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
new file mode 100644
index 0000000..89c9739
--- /dev/null
+++ b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2024 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 "CodecCapabilitiesTest"
+
+#include <utils/Log.h>
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include <binder/Parcel.h>
+
+#include <media/CodecCapabilities.h>
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/MediaCodecInfo.h>
+
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AString.h>
+
+using namespace android;
+
+class AudioCapsAacTest : public testing::Test {
+protected:
+ AudioCapsAacTest() {
+ std::string mediaType = MIMETYPE_AUDIO_AAC;
+
+ sp<AMessage> details = new AMessage;
+ details->setString("bitrate-range", "8000-960000");
+ details->setString("max-channel-count", "8");
+ details->setString("sample-rate-ranges",
+ "7350,8000,11025,12000,16000,22050,24000,32000,44100,48000");
+
+ std::vector<ProfileLevel> profileLevel{
+ ProfileLevel(2, 0),
+ ProfileLevel(5, 0),
+ ProfileLevel(29, 0),
+ ProfileLevel(23, 0),
+ ProfileLevel(39, 0),
+ ProfileLevel(20, 0),
+ ProfileLevel(42, 0),
+ };
+
+ audioCaps = AudioCapabilities::Create(mediaType, profileLevel, details);
+ }
+
+ std::shared_ptr<AudioCapabilities> audioCaps;
+};
+
+TEST_F(AudioCapsAacTest, AudioCaps_Aac_Bitrate) {
+ const Range<int>& bitrateRange = audioCaps->getBitrateRange();
+ EXPECT_EQ(bitrateRange.lower(), 8000) << "bitrate range1 does not match. lower: "
+ << bitrateRange.lower();
+ EXPECT_EQ(bitrateRange.upper(), 510000) << "bitrate range1 does not match. upper: "
+ << bitrateRange.upper();
+}
+
+TEST_F(AudioCapsAacTest, AudioCaps_Aac_InputChannelCount) {
+ int maxInputChannelCount = audioCaps->getMaxInputChannelCount();
+ EXPECT_EQ(maxInputChannelCount, 8);
+ int minInputChannelCount = audioCaps->getMinInputChannelCount();
+ EXPECT_EQ(minInputChannelCount, 1);
+}
+
+TEST_F(AudioCapsAacTest, AudioCaps_Aac_SupportedSampleRates) {
+ const std::vector<int>& sampleRates = audioCaps->getSupportedSampleRates();
+ EXPECT_EQ(sampleRates, std::vector<int>({7350, 8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000}));
+
+ EXPECT_FALSE(audioCaps->isSampleRateSupported(6000))
+ << "isSampleRateSupported returned true for unsupported sample rate";
+ EXPECT_TRUE(audioCaps->isSampleRateSupported(8000))
+ << "isSampleRateSupported returned false for supported sample rate";
+ EXPECT_TRUE(audioCaps->isSampleRateSupported(12000))
+ << "isSampleRateSupported returned false for supported sample rate";
+ EXPECT_FALSE(audioCaps->isSampleRateSupported(44000))
+ << "isSampleRateSupported returned true for unsupported sample rate";
+ EXPECT_TRUE(audioCaps->isSampleRateSupported(48000))
+ << "isSampleRateSupported returned true for unsupported sample rate";
+}
+
+class AudioCapsRawTest : public testing::Test {
+protected:
+ AudioCapsRawTest() {
+ std::string mediaType = MIMETYPE_AUDIO_RAW;
+
+ sp<AMessage> details = new AMessage;
+ details->setString("bitrate-range", "1-10000000");
+ details->setString("channel-ranges", "1,2,3,4,5,6,7,8,9,10,11,12");
+ details->setString("sample-rate-ranges", "8000-192000");
+
+ std::vector<ProfileLevel> profileLevel;
+
+ audioCaps = AudioCapabilities::Create(mediaType, profileLevel, details);
+ }
+
+ std::shared_ptr<AudioCapabilities> audioCaps;
+};
+
+TEST_F(AudioCapsRawTest, AudioCaps_Raw_Bitrate) {
+ const Range<int>& bitrateRange = audioCaps->getBitrateRange();
+ EXPECT_EQ(bitrateRange.lower(), 1);
+ EXPECT_EQ(bitrateRange.upper(), 10000000);
+}
+
+TEST_F(AudioCapsRawTest, AudioCaps_Raw_InputChannelCount) {
+ int maxInputChannelCount = audioCaps->getMaxInputChannelCount();
+ EXPECT_EQ(maxInputChannelCount, 12);
+ int minInputChannelCount = audioCaps->getMinInputChannelCount();
+ EXPECT_EQ(minInputChannelCount, 1);
+}
+
+TEST_F(AudioCapsRawTest, AudioCaps_Raw_InputChannelCountRanges) {
+ const std::vector<Range<int>>& inputChannelCountRanges
+ = audioCaps->getInputChannelCountRanges();
+ std::vector<Range<int>> expectedOutput({{1,1}, {2,2}, {3,3}, {4,4}, {5,5},
+ {6,6}, {7,7}, {8,8}, {9,9}, {10,10}, {11,11}, {12,12}});
+ ASSERT_EQ(inputChannelCountRanges.size(), expectedOutput.size());
+ for (int i = 0; i < inputChannelCountRanges.size(); i++) {
+ EXPECT_EQ(inputChannelCountRanges.at(i).lower(), expectedOutput.at(i).lower());
+ EXPECT_EQ(inputChannelCountRanges.at(i).upper(), expectedOutput.at(i).upper());
+ }
+}
+
+TEST_F(AudioCapsRawTest, AudioCaps_Raw_SupportedSampleRates) {
+ const std::vector<Range<int>>& sampleRateRanges = audioCaps->getSupportedSampleRateRanges();
+ EXPECT_EQ(sampleRateRanges.size(), 1);
+ EXPECT_EQ(sampleRateRanges.at(0).lower(), 8000);
+ EXPECT_EQ(sampleRateRanges.at(0).upper(), 192000);
+
+ EXPECT_EQ(audioCaps->isSampleRateSupported(7000), false);
+ EXPECT_EQ(audioCaps->isSampleRateSupported(10000), true);
+ EXPECT_EQ(audioCaps->isSampleRateSupported(193000), false);
+}
diff --git a/media/libmediaplayerservice/fuzzer/Android.bp b/media/libmediaplayerservice/fuzzer/Android.bp
index 78163e4..fcdaff9 100644
--- a/media/libmediaplayerservice/fuzzer/Android.bp
+++ b/media/libmediaplayerservice/fuzzer/Android.bp
@@ -64,6 +64,7 @@
"mediarecorder_fuzzer.cpp",
],
defaults: [
+ "libaudioflinger_dependencies",
"libmediaplayerserviceFuzzer_defaults",
],
static_libs: [
@@ -76,12 +77,10 @@
],
shared_libs: [
"android.hardware.media.omx@1.0",
- "av-types-aidl-cpp",
"media_permission-aidl-cpp",
- "libaudioclient_aidl_conversion",
"libactivitymanager_aidl",
"libandroid_net",
- "libaudioclient",
+ "libaudioflinger",
"libcamera_client",
"libcodec2_client",
"libcrypto",
@@ -89,24 +88,13 @@
"libdrmframework",
"libgui",
"libhidlbase",
- "liblog",
"libmedia_codeclist",
"libmedia_omx",
"libmediadrm",
- "libmediametrics",
- "libmediautils",
- "libmemunreachable",
"libnetd_client",
- "libpowermanager",
"libstagefright_httplive",
"packagemanager_aidl-cpp",
"libfakeservicemanager",
- "libvibrator",
- "libnbaio",
- "libnblog",
- "libpowermanager",
- "libaudioprocessing",
- "libaudioflinger",
"libresourcemanagerservice",
"libmediametricsservice",
"mediametricsservice-aidl-cpp",
@@ -122,10 +110,6 @@
"android.hardware.camera.device@3.4",
"libaudiohal@7.0",
],
- header_libs: [
- "libaudiohal_headers",
- "libaudioflinger_headers",
- ],
}
cc_fuzz {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 04364a8..717106b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -487,7 +487,7 @@
.id = getId(mClient),
.name = mCodecName,
.importance = mImportance};
- return std::move(clientInfo);
+ return clientInfo;
}
private:
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 6fb9232..c18ab94 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -332,7 +332,7 @@
<!-- profiles and levels: ProfileBaseline : Level3 -->
<Limit name="block-count" range="1-1620" />
<Limit name="blocks-per-second" range="1-40500" />
- <Limit name="bitrate" range="1-2000000" />
+ <Limit name="bitrate" range="1-10000000" />
</Variant>
<Feature name="intra-refresh" />
<!-- Video Quality control -->
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 4e4aa75..b1cf665 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -562,6 +562,30 @@
}
}
+inline constexpr int32_t DTS_HDProfileHRA = 0x1;
+inline constexpr int32_t DTS_HDProfileLBR = 0x2;
+inline constexpr int32_t DTS_HDProfileMA = 0x4;
+
+inline static const char *asString_Dts_HDProfile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case DTS_HDProfileHRA: return "HRA";
+ case DTS_HDProfileLBR: return "LBR";
+ case DTS_HDProfileMA: return "MA";
+ default: return def;
+ }
+}
+
+inline constexpr int32_t DTS_UHDProfileP1 = 0x1;
+inline constexpr int32_t DTS_UHDProfileP2 = 0x2;
+
+inline static const char *asString_Dts_UHDProfile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case DTS_UHDProfileP1: return "P1";
+ case DTS_UHDProfileP2: return "P2";
+ default: return def;
+ }
+}
+
inline constexpr int32_t BITRATE_MODE_CBR = 2;
inline constexpr int32_t BITRATE_MODE_CBR_FD = 3;
inline constexpr int32_t BITRATE_MODE_CQ = 0;
@@ -729,8 +753,13 @@
inline constexpr char MIMETYPE_AUDIO_FLAC[] = "audio/flac";
inline constexpr char MIMETYPE_AUDIO_MSGSM[] = "audio/gsm";
inline constexpr char MIMETYPE_AUDIO_AC3[] = "audio/ac3";
+inline constexpr char MIMETYPE_AUDIO_AC4[] = "audio/ac4";
inline constexpr char MIMETYPE_AUDIO_EAC3[] = "audio/eac3";
+inline constexpr char MIMETYPE_AUDIO_EAC3_JOC[] = "audio/eac3-joc";
inline constexpr char MIMETYPE_AUDIO_SCRAMBLED[] = "audio/scrambled";
+inline constexpr char MIMETYPE_AUDIO_DTS[] = "audio/vnd.dts";
+inline constexpr char MIMETYPE_AUDIO_DTS_HD[] = "audio/vnd.dts.hd";
+inline constexpr char MIMETYPE_AUDIO_DTS_UHD[] = "audio/vnd.dts.uhd";
inline constexpr char MIMETYPE_IMAGE_ANDROID_HEIC[] = "image/vnd.android.heic";
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 4183023..4ab5d10 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -619,6 +619,13 @@
if (!isValidOMXParam(outParams)) {
return OMX_ErrorBadParameter;
}
+ if (offsetof(DescribeHDR10PlusInfoParams, nValue) + outParams->nParamSize >
+ outParams->nSize) {
+ ALOGE("b/329641908: too large param size; nParamSize=%u nSize=%u",
+ outParams->nParamSize, outParams->nSize);
+ android_errorWriteLog(0x534e4554, "329641908");
+ return OMX_ErrorBadParameter;
+ }
outParams->nParamSizeUsed = info->size();
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index ca862b0..151ce7c 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -290,7 +290,7 @@
// Max file duration limit is set
if (mMaxFileDurationLimitUs != 0) {
if (bitRate > 0) {
- int64_t size2 = ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
+ int64_t size2 = ((mMaxFileDurationLimitUs / 1000) * bitRate * 6) / 8000000;
if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
// When both file size and duration limits are set,
// we use the smaller limit of the two.
diff --git a/media/module/bufferpool/2.0/BufferPoolClient.cpp b/media/module/bufferpool/2.0/BufferPoolClient.cpp
index cda23ff..66d11fa 100644
--- a/media/module/bufferpool/2.0/BufferPoolClient.cpp
+++ b/media/module/bufferpool/2.0/BufferPoolClient.cpp
@@ -762,6 +762,10 @@
} else {
connection = mRemoteConnection;
}
+ if (!connection) {
+ ALOGE("connection null: fetchBufferHandle()");
+ return ResultStatus::CRITICAL_ERROR;
+ }
ResultStatus status;
Return<void> transResult = connection->fetch(
transactionId, bufferId,
diff --git a/media/module/codecs/amrnb/common/include/abs_s.h b/media/module/codecs/amrnb/common/include/abs_s.h
deleted file mode 100644
index e92eaf4..0000000
--- a/media/module/codecs/amrnb/common/include/abs_s.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Pathname: ./gsm-amr/c/include/abs_s.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for abs_s function.
-
- Description: Updated template to make it build for Symbian.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the abs_s function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef ABS_S_H
-#define ABS_S_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
- Word16 abs_s(Word16 var1);
-
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ABS_S_H */
-
-
diff --git a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
index 8f0867a..8817621 100644
--- a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
+++ b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
@@ -120,15 +120,11 @@
{
Word32 L_sum;
- L_sum = L_var1 + L_var2;
-
- if ((L_var1 ^ L_var2) >= 0)
+ if (__builtin_add_overflow(L_var1, L_var2, &L_sum))
{
- if ((L_sum ^ L_var1) < 0)
- {
- L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_sum);
@@ -160,15 +156,11 @@
{
Word32 L_diff;
- L_diff = L_var1 - L_var2;
-
- if ((L_var1 ^ L_var2) < 0)
+ if (__builtin_sub_overflow(L_var1, L_var2, &L_diff))
{
- if ((L_diff ^ L_var1) & MIN_32)
- {
- L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_diff);
@@ -204,16 +196,12 @@
result = (Word32) var1 * var2;
if (result != (Word32) 0x40000000L)
{
- L_sum = (result << 1) + L_var3;
-
/* Check if L_sum and L_var_3 share the same sign */
- if ((L_var3 ^ result) > 0)
+ if (__builtin_add_overflow((result << 1), L_var3, &L_sum))
{
- if ((L_sum ^ L_var3) < 0)
- {
- L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
}
else
@@ -345,14 +333,10 @@
product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15;
/* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
+ if (__builtin_add_overflow(L_product, (product32 << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
}
L_product = L_sum;
@@ -361,14 +345,10 @@
product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15;
/* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
+ if (__builtin_add_overflow(L_product, (product32 << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
}
return (L_sum);
}
@@ -416,15 +396,11 @@
result = ((Word32)L_var1_lo * var2) >> 15;
- L_sum = L_product + (result << 1);
-
- if ((L_product ^ result) > 0)
+ if (__builtin_add_overflow(L_product, (result << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_sum);
diff --git a/media/module/codecs/amrnb/common/include/l_add.h b/media/module/codecs/amrnb/common/include/l_add.h
deleted file mode 100644
index 136b914..0000000
--- a/media/module/codecs/amrnb/common/include/l_add.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/l_add.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_add function.
-
- Description: Changed function prototype declaration. A pointer to the overflow
- flag is being passed in as a parameter instead of using global
- data.
-
- Description: Updated template. Changed paramter name from overflow to
- pOverflow
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Providing support for ARM and Linux-ARM assembly instructions.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_add function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_ADD_H
-#define L_ADD_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
- {
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
- __asm
- {
- QADD result, L_var1, L_var2
- }
- return(result);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
- {
- register Word32 ra = L_var1;
- register Word32 rb = L_var2;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("qadd %0, %1, %2"
- : "=r"(result)
- : "r"(ra), "r"(rb)
- );
- return (result);
-
- }
-
-#else /* C EQUIVALENT */
-
-
- static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
- {
- Word32 L_sum;
-
- L_sum = L_var1 + L_var2;
-
- if ((L_var1 ^ L_var2) >= 0)
- {
- if ((L_sum ^ L_var1) < 0)
- {
- L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
- }
-
- return (L_sum);
- }
-
-#endif
-
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_ADD_H_ */
diff --git a/media/module/codecs/amrnb/common/include/l_add_c.h b/media/module/codecs/amrnb/common/include/l_add_c.h
deleted file mode 100644
index 3585a3c..0000000
--- a/media/module/codecs/amrnb/common/include/l_add_c.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/l_add_c.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_add_c function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag and carry flag is passed into the
- function. Updated template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_add_c function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_ADD_C_H
-#define L_ADD_C_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
- Word32 L_add_c(Word32 L_var1, Word32 L_var2, Flag *pOverflow, Flag *pCarry);
-
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_ADD_C_H_ */
-
-
diff --git a/media/module/codecs/amrnb/common/include/l_mac.h b/media/module/codecs/amrnb/common/include/l_mac.h
deleted file mode 100644
index b4af3aa..0000000
--- a/media/module/codecs/amrnb/common/include/l_mac.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
- Filename: /audio/gsm_amr/c/include/l_mac.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_mac function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: 1. Updated the function to include ARM and Linux-ARM assembly
- instructions.
- 2. Added OSCL_UNUSED_ARG(pOverflow) to remove compiler warnings.
-
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_mac function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_MAC_H
-#define L_MAC_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 result;
- Word32 L_sum;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm {SMULBB result, var1, var2}
- __asm {QDADD L_sum, L_var3, result}
- return (L_sum);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 ra = L_var3;
- register Word32 rb = var1;
- register Word32 rc = var2;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(result)
- : "r"(rb), "r"(rc)
- );
-
- asm volatile("qdadd %0, %1, %2"
- : "=r"(rc)
- : "r"(ra), "r"(result)
- );
-
- return (rc);
- }
-
-#else /* C_EQUIVALENT */
-
- __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 result;
- Word32 L_sum;
- result = (Word32) var1 * var2;
- if (result != (Word32) 0x40000000L)
- {
- L_sum = (result << 1) + L_var3;
-
- /* Check if L_sum and L_var_3 share the same sign */
- if ((L_var3 ^ result) > 0)
- {
- if ((L_sum ^ L_var3) < 0)
- {
- L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
- }
- }
- else
- {
- *pOverflow = 1;
- L_sum = MAX_32;
- }
- return (L_sum);
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_MAC_H_ */
-
-
diff --git a/media/module/codecs/amrnb/common/include/l_msu.h b/media/module/codecs/amrnb/common/include/l_msu.h
deleted file mode 100644
index 3bafb00..0000000
--- a/media/module/codecs/amrnb/common/include/l_msu.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
- Filename: /audio/gsm_amr/c/include/l_msu.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_msu function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Providing support for ARM and Linux-ARM assembly instructions.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_msu function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_MSU_H
-#define L_MSU_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-#include "l_mult.h"
-#include "l_sub.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 product;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm
- {
- SMULBB product, var1, var2
- QDSUB result, L_var3, product
- }
-
- return (result);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 ra = L_var3;
- register Word32 rb = var1;
- register Word32 rc = var2;
- Word32 product;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(product)
- : "r"(rb), "r"(rc)
- );
-
- asm volatile("qdsub %0, %1, %2"
- : "=r"(result)
- : "r"(ra), "r"(product)
- );
-
- return (result);
- }
-
-#else /* C EQUIVALENT */
-
- static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 result;
-
- result = L_mult(var1, var2, pOverflow);
- result = L_sub(L_var3, result, pOverflow);
-
- return (result);
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_MSU_H_ */
diff --git a/media/module/codecs/amrnb/common/include/l_mult.h b/media/module/codecs/amrnb/common/include/l_mult.h
deleted file mode 100644
index 061df60..0000000
--- a/media/module/codecs/amrnb/common/include/l_mult.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/l_mult.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_mult function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Providing support for ARM and Linux-ARM assembly instructions.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_mult function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_MULT_H
-#define L_MULT_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 result;
- Word32 product;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm
- {
- SMULBB product, var1, var2
- QADD result, product, product
- }
-
- return (result);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 ra = var1;
- register Word32 rb = var2;
- Word32 result;
- Word32 product;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(product)
- : "r"(ra), "r"(rb)
- );
-
- asm volatile("qadd %0, %1, %2"
- : "=r"(result)
- : "r"(product), "r"(product)
- );
-
- return(result);
- }
-
-#else /* C EQUIVALENT */
-
- static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 L_product;
-
- L_product = (Word32) var1 * var2;
-
- if (L_product != (Word32) 0x40000000L)
- {
- L_product <<= 1; /* Multiply by 2 */
- }
- else
- {
- *pOverflow = 1;
- L_product = MAX_32;
- }
-
- return (L_product);
- }
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_MULT_H */
-
diff --git a/media/module/codecs/amrnb/common/include/l_shl.h b/media/module/codecs/amrnb/common/include/l_shl.h
deleted file mode 100644
index 7b9fdb1..0000000
--- a/media/module/codecs/amrnb/common/include/l_shl.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/l_shl.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_shl function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_shl function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_SHL_H
-#define L_SHL_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
- Word32 L_shl(Word32 L_var1, Word16 var2, Flag *pOverflow);
-
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_SHL_H_ */
-
-
-
diff --git a/media/module/codecs/amrnb/common/include/l_shr.h b/media/module/codecs/amrnb/common/include/l_shr.h
deleted file mode 100644
index ef22073..0000000
--- a/media/module/codecs/amrnb/common/include/l_shr.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
- Filename: /audio/gsm_amr/c/include/l_shr.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_shr function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_shr function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_SHR_H
-#define L_SHR_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
- Word32 L_shr(Word32 L_var1, Word16 var2, Flag *pOverflow);
-
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_SHR_H_ */
-
-
-
diff --git a/media/module/codecs/amrnb/common/include/l_sub.h b/media/module/codecs/amrnb/common/include/l_sub.h
deleted file mode 100644
index 97d7538..0000000
--- a/media/module/codecs/amrnb/common/include/l_sub.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/l_sub.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for L_sub function.
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Providing support for ARM and Linux-ARM assembly instructions.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the L_sub function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef L_SUB_H
-#define L_SUB_H
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
- {
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm
- {
- QSUB result, L_var1, L_var2
- }
-
- return(result);
-
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
- {
- register Word32 ra = L_var1;
- register Word32 rb = L_var2;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("qsub %0, %1, %2"
- : "=r"(result)
- : "r"(ra), "r"(rb)
- );
-
- return (result);
- }
-
-#else /* C EQUIVALENT */
-
- static inline Word32 L_sub(register Word32 L_var1, register Word32 L_var2,
- register Flag *pOverflow)
- {
- Word32 L_diff;
-
- L_diff = L_var1 - L_var2;
-
- if ((L_var1 ^ L_var2) < 0)
- {
- if ((L_diff ^ L_var1) & MIN_32)
- {
- L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
- }
-
- return (L_diff);
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _L_SUB_H_ */
-
-
diff --git a/media/module/codecs/amrnb/common/include/mpy_32.h b/media/module/codecs/amrnb/common/include/mpy_32.h
deleted file mode 100644
index 03f36b2..0000000
--- a/media/module/codecs/amrnb/common/include/mpy_32.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/mpy_32.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Updated function prototype declaration to reflect new interface.
- A pointer to overflow flag is passed into the function. Updated
- template.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Updated the function to include ARM and Linux-ARM assembly
- instructions.
-
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the Mpy_32 function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef MPY_32_H
-#define MPY_32_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 Mpy_32(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 L_var2_hi,
- Word16 L_var2_lo,
- Flag *pOverflow)
-
- {
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- Word32 L_product;
- Word32 L_sum;
- Word32 product32;
-
- OSCL_UNUSED_ARG(pOverflow);
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* L_product = L_mult (L_var1_hi, L_var2_hi, pOverflow);*/
-
- __asm {SMULBB L_product, L_var1_hi, L_var2_hi}
- __asm {QDADD L_product, 0, L_product}
- __asm {SMULBB product32, L_var1_hi, L_var2_lo}
- product32 >>= 15;
- __asm {QDADD L_sum, L_product, product32}
- L_product = L_sum;
- __asm {SMULBB product32, L_var1_lo, L_var2_hi}
- product32 >>= 15;
- __asm {QDADD L_sum, L_product, product32}
- return (L_sum);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- static inline Word32 Mpy_32(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 L_var2_hi,
- Word16 L_var2_lo,
- Flag *pOverflow)
- {
- register Word32 product32;
- register Word32 L_sum;
- register Word32 L_product, result;
- register Word32 ra = L_var1_hi;
- register Word32 rb = L_var1_lo;
- register Word32 rc = L_var2_hi;
- register Word32 rd = L_var2_lo;
-
-
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(L_product)
- : "r"(ra), "r"(rc)
- );
- asm volatile("mov %0, #0"
- : "=r"(result)
- );
-
- asm volatile("qdadd %0, %1, %2"
- : "=r"(L_sum)
- : "r"(result), "r"(L_product)
- );
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(product32)
- : "r"(ra), "r"(rd)
- );
-
- asm volatile("mov %0, %1, ASR #15"
- : "=r"(ra)
- : "r"(product32)
- );
- asm volatile("qdadd %0, %1, %2"
- : "=r"(L_product)
- : "r"(L_sum), "r"(ra)
- );
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(product32)
- : "r"(rb), "r"(rc)
- );
-
- asm volatile("mov %0, %1, ASR #15"
- : "=r"(rb)
- : "r"(product32)
- );
-
- asm volatile("qdadd %0, %1, %2"
- : "=r"(L_sum)
- : "r"(L_product), "r"(rb)
- );
-
- return (L_sum);
- }
-
-#else /* C_EQUIVALENT */
-
- __inline Word32 Mpy_32(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 L_var2_hi,
- Word16 L_var2_lo,
- Flag *pOverflow)
- {
- Word32 L_product;
- Word32 L_sum;
- Word32 product32;
-
- OSCL_UNUSED_ARG(pOverflow);
- L_product = (Word32) L_var1_hi * L_var2_hi;
-
- if (L_product != (Word32) 0x40000000L)
- {
- L_product <<= 1;
- }
- else
- {
- L_product = MAX_32;
- }
-
- /* result = mult (L_var1_hi, L_var2_lo, pOverflow); */
- product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15;
-
- /* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
- {
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
- }
-
- L_product = L_sum;
-
- /* result = mult (L_var1_lo, L_var2_hi, pOverflow); */
- product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15;
-
- /* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
- {
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
- }
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return (L_sum);
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MPY_32_H_ */
diff --git a/media/module/codecs/amrnb/common/include/mpy_32_16.h b/media/module/codecs/amrnb/common/include/mpy_32_16.h
deleted file mode 100644
index 7eaa741..0000000
--- a/media/module/codecs/amrnb/common/include/mpy_32_16.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/mpy_32_16.h
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the Mpy_32_16 function.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef MPY_32_16_H
-#define MPY_32_16_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
-
- __inline Word32 Mpy_32_16(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 var2,
- Flag *pOverflow)
- {
-
- Word32 L_product;
- Word32 L_sum;
- Word32 result;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm {SMULBB L_product, L_var1_hi, var2}
- __asm {QDADD L_product, 0, L_product}
- __asm {SMULBB result, L_var1_lo, var2}
- result >>= 15;
- __asm {QDADD L_sum, L_product, result}
- return (L_sum);
- }
-
-#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
-
- static inline Word32 Mpy_32_16(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 var2,
- Flag *pOverflow)
- {
-
- register Word32 ra = L_var1_hi;
- register Word32 rb = L_var1_lo;
- register Word32 rc = var2;
- Word32 result, L_product;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(L_product)
- : "r"(ra), "r"(rc)
- );
- asm volatile("mov %0, #0"
- : "=r"(result)
- );
-
- asm volatile("qdadd %0, %1, %2"
- : "=r"(L_product)
- : "r"(result), "r"(L_product)
- );
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(result)
- : "r"(rb), "r"(rc)
- );
-
- asm volatile("mov %0, %1, ASR #15"
- : "=r"(ra)
- : "r"(result)
- );
- asm volatile("qdadd %0, %1, %2"
- : "=r"(result)
- : "r"(L_product), "r"(ra)
- );
-
- return (result);
- }
-
-#else /* C_EQUIVALENT */
- __inline Word32 Mpy_32_16(Word16 L_var1_hi,
- Word16 L_var1_lo,
- Word16 var2,
- Flag *pOverflow)
- {
-
- Word32 L_product;
- Word32 L_sum;
- Word32 result;
- L_product = (Word32) L_var1_hi * var2;
-
- if (L_product != (Word32) 0x40000000L)
- {
- L_product <<= 1;
- }
- else
- {
- *pOverflow = 1;
- L_product = MAX_32;
- }
-
- result = ((Word32)L_var1_lo * var2) >> 15;
-
- L_sum = L_product + (result << 1);
-
- if ((L_product ^ result) > 0)
- {
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
- }
- return (L_sum);
-
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MPY_32_16_H_ */
-
-
diff --git a/media/module/codecs/amrnb/common/include/mult.h b/media/module/codecs/amrnb/common/include/mult.h
deleted file mode 100644
index 6927eba..0000000
--- a/media/module/codecs/amrnb/common/include/mult.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/include/mult.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Created separate header file for mult function.
-
- Description: Changed prototype of the mult() function. Instead of using global
- a pointer to overflow flag is now passed into the function.
-
- Description: Updated copyright information.
- Updated variable name from "overflow" to "pOverflow" to match
- with original function declaration.
-
- Description: Moved _cplusplus #ifdef after Include section.
-
- Description: Providing support for ARM and Linux-ARM assembly instructions.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file contains all the constant definitions and prototype definitions
- needed by the mult function.
-
-------------------------------------------------------------------------------
-*/
-
-#ifndef MULT_H
-#define MULT_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-
-#include "basicop_malloc.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /*----------------------------------------------------------------------------
- ; MACROS
- ; Define module specific macros here
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; DEFINES
- ; Include all pre-processor statements here.
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; EXTERNAL VARIABLES REFERENCES
- ; Declare variables used in this module but defined elsewhere
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; SIMPLE TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; ENUMERATED TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; STRUCTURES TYPEDEF'S
- ----------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------------
- ; GLOBAL FUNCTION DEFINITIONS
- ; Function Prototype declaration
- ----------------------------------------------------------------------------*/
-#if defined(PV_ARM_V5)
-
- __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- Word32 product;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- __asm
- {
- SMULBB product, var1, var2
- MOV product, product, ASR #15
- CMP product, 0x7FFF
- MOVGE product, 0x7FFF
- }
-
- return ((Word16) product);
- }
-
-#elif defined(PV_ARM_GCC_V5)
-
- __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 ra = var1;
- register Word32 rb = var2;
- Word32 product;
- Word32 temp = 0x7FFF;
-
- OSCL_UNUSED_ARG(pOverflow);
-
- asm volatile("smulbb %0, %1, %2"
- : "=r"(product)
- : "r"(ra), "r"(rb)
- );
- asm volatile("mov %0, %1, ASR #15"
- : "=r"(product)
- : "r"(product)
- );
- asm volatile("cmp %0, %1"
- : "=r"(product)
- : "r"(temp)
- );
- asm volatile("movge %0, %1"
- : "=r"(product)
- : "r"(temp)
- );
-
- return ((Word16) product);
- }
-
-#else /* C EQUIVALENT */
-
- static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
- {
- register Word32 product;
-
- product = ((Word32) var1 * var2) >> 15;
-
- /* Saturate result (if necessary). */
- /* var1 * var2 >0x00007fff is the only case */
- /* that saturation occurs. */
-
- if (product > 0x00007fffL)
- {
- *pOverflow = 1;
- product = (Word32) MAX_16;
- }
-
-
- /* Return the product as a 16 bit value by type casting Word32 to Word16 */
-
- return ((Word16) product);
- }
-
-#endif
- /*----------------------------------------------------------------------------
- ; END
- ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MULT_H_ */
-
diff --git a/media/module/codecs/amrnb/common/include/n_proc.h b/media/module/codecs/amrnb/common/include/n_proc.h
deleted file mode 100644
index e5738c1..0000000
--- a/media/module/codecs/amrnb/common/include/n_proc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/* $Id $ */
-
-void proc_head(char *mes);
diff --git a/media/module/codecs/amrnb/enc/src/g_pitch.cpp b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
index 5b80e2a..6f686fa 100644
--- a/media/module/codecs/amrnb/enc/src/g_pitch.cpp
+++ b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
@@ -376,15 +376,11 @@
{
L_temp = ((Word32) * (p_xn++) * *(p_y1++));
s1 = s;
- s = s1 + L_temp;
- if ((s1 ^ L_temp) > 0)
+ if (__builtin_add_overflow(s1, L_temp, &s))
{
- if ((s1 ^ s) < 0)
- {
- *pOverflow = 1;
- break;
- }
+ *pOverflow = 1;
+ break;
}
}
diff --git a/media/module/codecs/amrwb/enc/inc/basic_op.h b/media/module/codecs/amrwb/enc/inc/basic_op.h
index 80ad7f1..8e740b4 100644
--- a/media/module/codecs/amrwb/enc/inc/basic_op.h
+++ b/media/module/codecs/amrwb/enc/inc/basic_op.h
@@ -569,13 +569,10 @@
static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
- L_var_out = L_var1 + L_var2;
- if (((L_var1 ^ L_var2) & MIN_32) == 0)
+ if (__builtin_add_overflow(L_var1, L_var2, &L_var_out))
{
- if ((L_var_out ^ L_var1) & MIN_32)
- {
- L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
}
return (L_var_out);
}
@@ -616,13 +613,10 @@
static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
- L_var_out = L_var1 - L_var2;
- if (((L_var1 ^ L_var2) & MIN_32) != 0)
+ if (__builtin_sub_overflow(L_var1, L_var2, &L_var_out))
{
- if ((L_var_out ^ L_var1) & MIN_32)
- {
- L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
}
return (L_var_out);
}
diff --git a/media/module/codecserviceregistrant/Android.bp b/media/module/codecserviceregistrant/Android.bp
index becb98a..56cd8b8 100644
--- a/media/module/codecserviceregistrant/Android.bp
+++ b/media/module/codecserviceregistrant/Android.bp
@@ -55,6 +55,8 @@
"com.android.media.swcodec",
],
+ export_include_dirs: ["include"],
+
srcs: [
"CodecServiceRegistrant.cpp",
],
diff --git a/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
index 6df9dc8..42fd94e 100644
--- a/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
+++ b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
@@ -40,7 +40,7 @@
#include <codec2/aidl/ComponentStore.h>
#include <codec2/aidl/ParamTypes.h>
-#include <media/CodecServiceRegistrant.h>
+#include <codecserviceregistrant/CodecServiceRegistrant.h>
namespace /* unnamed */ {
@@ -775,13 +775,12 @@
return nullptr;
}
-extern "C" void RegisterCodecServices() {
+/**
+ * This function encapsulates the core logic required to register codec services,
+ * separated from threadpool management to avoid timeouts when called by the fuzzer.
+ */
+static void RegisterCodecServicesWithExistingThreadpool() {
const bool aidlSelected = c2_aidl::utils::IsSelected();
- constexpr int kThreadCount = 64;
- ABinderProcess_setThreadPoolMaxThreadCount(kThreadCount);
- ABinderProcess_startThreadPool();
- ::android::hardware::configureRpcThreadpool(kThreadCount, false);
-
LOG(INFO) << "Creating software Codec2 service...";
std::shared_ptr<C2ComponentStore> store =
android::GetCodec2PlatformComponentStore();
@@ -880,8 +879,16 @@
if (registered) {
LOG(INFO) << "Software Codec2 service created and registered.";
}
+}
+
+extern "C" void RegisterCodecServices() {
+ constexpr int kThreadCount = 64;
+ ABinderProcess_setThreadPoolMaxThreadCount(kThreadCount);
+ ABinderProcess_startThreadPool();
+ ::android::hardware::configureRpcThreadpool(kThreadCount, false);
+
+ RegisterCodecServicesWithExistingThreadpool();
ABinderProcess_joinThreadPool();
::android::hardware::joinRpcThreadpool();
}
-
diff --git a/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp b/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
index 4868e0c..0baf1ca 100644
--- a/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
+++ b/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
@@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#include <codecserviceregistrant/CodecServiceRegistrant.h>
+
#include "../CodecServiceRegistrant.cpp"
#include "fuzzer/FuzzedDataProvider.h"
#include <C2Config.h>
@@ -166,9 +169,9 @@
void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) {
mFDP = new FuzzedDataProvider(data, size);
invokeH2C2ComponentStore();
- /** RegisterCodecServices is called here to improve code coverage */
- /** as currently it is not called by codecServiceRegistrant */
- RegisterCodecServices();
+ /** RegisterCodecServicesWithExistingThreadpool() is called here to improve
+ * code coverage as currently it is not called in codecServiceRegistrant.cpp */
+ RegisterCodecServicesWithExistingThreadpool();
delete mFDP;
}
diff --git a/media/libmedia/include/media/CodecServiceRegistrant.h b/media/module/codecserviceregistrant/include/codecserviceregistrant/CodecServiceRegistrant.h
similarity index 77%
rename from media/libmedia/include/media/CodecServiceRegistrant.h
rename to media/module/codecserviceregistrant/include/codecserviceregistrant/CodecServiceRegistrant.h
index e0af781..1c6f71f 100644
--- a/media/libmedia/include/media/CodecServiceRegistrant.h
+++ b/media/module/codecserviceregistrant/include/codecserviceregistrant/CodecServiceRegistrant.h
@@ -18,6 +18,13 @@
#define CODEC_SERVICE_REGISTRANT_H_
+/**
+ * This function starts the threadpool, calls the registration logic
+ * encapsulated in RegisterCodecServicesWithExistingThreadpool(), and
+ * then stops the threadpool.
+ */
+extern "C" void RegisterCodecServices();
+
typedef void (*RegisterCodecServicesFunc)();
#endif // CODEC_SERVICE_REGISTRANT_H_
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index b3707c8..f247f8c 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -523,11 +523,10 @@
}
[this, &track] {
- int64_t duration;
+ int64_t duration = track->mMdhdDurationUs;
int32_t samplerate;
// Only for audio track.
- if (track->elst_needs_processing && mHeaderTimescale != 0 &&
- AMediaFormat_getInt64(track->meta, AMEDIAFORMAT_KEY_DURATION, &duration) &&
+ if (track->elst_needs_processing && mHeaderTimescale != 0 && duration != 0 &&
AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &samplerate)) {
// Elst has to be processed only the first time this function is called.
track->elst_needs_processing = false;
@@ -1645,7 +1644,10 @@
(long long) duration, (long long) mLastTrack->timescale);
return ERROR_MALFORMED;
}
- AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
+ // Store this track's mdhd duration to calculate the padding.
+ mLastTrack->mMdhdDurationUs = (int64_t)durationUs;
+ } else {
+ mLastTrack->mMdhdDurationUs = 0;
}
uint8_t lang[2];
@@ -3907,17 +3909,18 @@
}
int32_t id;
+ int64_t duration;
if (version == 1) {
// we can get ctime value from U64_AT(&buffer[4])
// we can get mtime value from U64_AT(&buffer[12])
id = U32_AT(&buffer[20]);
- // we can get duration value from U64_AT(&buffer[28])
+ duration = U64_AT(&buffer[28]);
} else if (version == 0) {
// we can get ctime value from U32_AT(&buffer[4])
// we can get mtime value from U32_AT(&buffer[8])
id = U32_AT(&buffer[12]);
- // we can get duration value from U32_AT(&buffer[20])
+ duration = U32_AT(&buffer[20]);
} else {
return ERROR_UNSUPPORTED;
}
@@ -3926,6 +3929,15 @@
return ERROR_MALFORMED;
AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_TRACK_ID, id);
+ if (duration != 0 && mHeaderTimescale != 0) {
+ long double durationUs = ((long double)duration * 1000000) / mHeaderTimescale;
+ if (durationUs < 0 || durationUs > INT64_MAX) {
+ ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
+ (long long) duration, (long long) mHeaderTimescale);
+ return ERROR_MALFORMED;
+ }
+ AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
+ }
size_t matrixOffset = dynSize + 16;
int32_t a00 = U32_AT(&buffer[matrixOffset]);
diff --git a/media/module/extractors/mp4/include/MPEG4Extractor.h b/media/module/extractors/mp4/include/MPEG4Extractor.h
index 542a3e6..59626f6 100644
--- a/media/module/extractors/mp4/include/MPEG4Extractor.h
+++ b/media/module/extractors/mp4/include/MPEG4Extractor.h
@@ -96,7 +96,7 @@
uint8_t *mTx3gBuffer;
size_t mTx3gSize, mTx3gFilled;
-
+ int64_t mMdhdDurationUs;
Track() {
next = NULL;
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index ec68de7..658191e 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -23,6 +23,7 @@
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <audio_utils/clock.h>
+#include <cutils/properties.h>
#include <mediautils/EventLog.h>
#include <mediautils/FixedString.h>
#include <mediautils/MethodStatistics.h>
@@ -36,6 +37,46 @@
namespace android::mediautils {
+
+// Note: The sum of kDefaultTimeOutDurationMs and kDefaultSecondChanceDurationMs
+// should be no less than 2 seconds, otherwise spurious timeouts
+// may occur with system suspend.
+static constexpr int kDefaultTimeoutDurationMs = 3000;
+
+// Due to suspend abort not incrementing the monotonic clock,
+// we allow another second chance timeout after the first timeout expires.
+//
+// The total timeout is therefore kDefaultTimeoutDuration + kDefaultSecondChanceDuration,
+// and the result is more stable when the monotonic clock increments during suspend.
+//
+static constexpr int kDefaultSecondChanceDurationMs = 2000;
+
+/* static */
+TimeCheck::Duration TimeCheck::getDefaultTimeoutDuration() {
+ static constinit std::atomic<int> defaultTimeoutDurationMs{};
+ auto defaultMs = defaultTimeoutDurationMs.load(std::memory_order_relaxed);
+ if (defaultMs == 0) {
+ defaultMs = property_get_int32(
+ "audio.timecheck.timeout_duration_ms", kDefaultTimeoutDurationMs);
+ if (defaultMs < 1) defaultMs = kDefaultTimeoutDurationMs;
+ defaultTimeoutDurationMs.store(defaultMs, std::memory_order_relaxed);
+ }
+ return std::chrono::milliseconds(defaultMs);
+}
+
+/* static */
+TimeCheck::Duration TimeCheck::getDefaultSecondChanceDuration() {
+ static constinit std::atomic<int> defaultSecondChanceDurationMs{};
+ auto defaultMs = defaultSecondChanceDurationMs.load(std::memory_order_relaxed);
+ if (defaultMs == 0) {
+ defaultMs = property_get_int32(
+ "audio.timecheck.second_chance_duration_ms", kDefaultSecondChanceDurationMs);
+ if (defaultMs < 1) defaultMs = kDefaultSecondChanceDurationMs;
+ defaultSecondChanceDurationMs.store(defaultMs, std::memory_order_relaxed);
+ }
+ return std::chrono::milliseconds(defaultMs);
+}
+
// This function appropriately signals a pid to dump a backtrace if we are
// running on device (and the HAL exists). If we are not running on an Android
// device, there is no HAL to signal (so we do nothing).
@@ -182,23 +223,25 @@
/* static */
std::string TimeCheck::analyzeTimeouts(
- float requestedTimeoutMs, float elapsedSteadyMs, float elapsedSystemMs) {
+ float requestedTimeoutMs, float secondChanceMs,
+ float elapsedSteadyMs, float elapsedSystemMs) {
// Track any OS clock issues with suspend.
// It is possible that the elapsedSystemMs is much greater than elapsedSteadyMs if
// a suspend occurs; however, we always expect the timeout ms should always be slightly
// less than the elapsed steady ms regardless of whether a suspend occurs or not.
- std::string s("Timeout ms ");
- s.append(std::to_string(requestedTimeoutMs))
- .append(" elapsed steady ms ").append(std::to_string(elapsedSteadyMs))
- .append(" elapsed system ms ").append(std::to_string(elapsedSystemMs));
+ const float totalTimeoutMs = requestedTimeoutMs + secondChanceMs;
+ std::string s = std::format(
+ "Timeout ms {:.2f} ({:.2f} + {:.2f})"
+ " elapsed steady ms {:.4f} elapsed system ms {:.4f}",
+ totalTimeoutMs, requestedTimeoutMs, secondChanceMs, elapsedSteadyMs, elapsedSystemMs);
// Is there something unusual?
static constexpr float TOLERANCE_CONTEXT_SWITCH_MS = 200.f;
- if (requestedTimeoutMs > elapsedSteadyMs || requestedTimeoutMs > elapsedSystemMs) {
+ if (totalTimeoutMs > elapsedSteadyMs || totalTimeoutMs > elapsedSystemMs) {
s.append("\nError: early expiration - "
- "requestedTimeoutMs should be less than elapsed time");
+ "totalTimeoutMs should be less than elapsed time");
}
if (elapsedSteadyMs > elapsedSystemMs + TOLERANCE_CONTEXT_SWITCH_MS) {
@@ -206,13 +249,13 @@
}
// This has been found in suspend stress testing.
- if (elapsedSteadyMs > requestedTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
+ if (elapsedSteadyMs > totalTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
s.append("\nWarning: steady time significantly exceeds timeout "
"- possible thread stall or aborted suspend");
}
// This has been found in suspend stress testing.
- if (elapsedSystemMs > requestedTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
+ if (elapsedSystemMs > totalTimeoutMs + TOLERANCE_CONTEXT_SWITCH_MS) {
s.append("\nInformation: system time significantly exceeds timeout "
"- possible suspend");
}
@@ -282,7 +325,7 @@
.append(tag)
.append(" scheduled ").append(formatTime(startSystemTime))
.append(" on thread ").append(std::to_string(tid)).append("\n")
- .append(analyzeTimeouts(requestedTimeoutMs + secondChanceMs,
+ .append(analyzeTimeouts(requestedTimeoutMs, secondChanceMs,
elapsedSteadyMs, elapsedSystemMs)).append("\n")
.append(halPids).append("\n")
.append(snapshotAnalysis.toString());
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index f1d572f..3e8d35d 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -42,19 +42,29 @@
// float elapsedMs (the elapsed time to this event).
using OnTimerFunc = std::function<void(bool /* timeout */, float /* elapsedMs */ )>;
- // The default timeout is chosen to be less than system server watchdog timeout
- // Note: kDefaultTimeOutMs should be no less than 2 seconds, otherwise spurious timeouts
- // may occur with system suspend.
- static constexpr TimeCheck::Duration kDefaultTimeoutDuration = std::chrono::milliseconds(3000);
+ /**
+ * Returns the default timeout to use for TimeCheck.
+ *
+ * The default timeout of 3000ms (kDefaultTimeoutDurationMs) is chosen to be less than
+ * the system server watchdog timeout, and can be changed by the sysprop
+ * audio.timecheck.timeout_duration_ms.
+ * A second chance wait may be set to extend the check.
+ */
+ static TimeCheck::Duration getDefaultTimeoutDuration();
- // Due to suspend abort not incrementing the monotonic clock,
- // we allow another second chance timeout after the first timeout expires.
- //
- // The total timeout is therefore kDefaultTimeoutDuration + kDefaultSecondChanceDuration,
- // and the result is more stable when the monotonic clock increments during suspend.
- //
- static constexpr TimeCheck::Duration kDefaultSecondChanceDuration =
- std::chrono::milliseconds(2000);
+ /**
+ * Returns the second chance timeout to use for TimeCheck.
+ *
+ * Due to suspend abort not incrementing the monotonic clock,
+ * we allow another second chance timeout after the first timeout expires.
+ * The second chance timeout default of 2000ms (kDefaultSecondChanceDurationMs)
+ * may be changed by the sysprop audio.timecheck.second_chance_duration_ms.
+ *
+ * The total timeout is therefore
+ * getDefaultTimeoutDuration() + getDefaultSecondChanceDuration(),
+ * and the result is more stable when the monotonic clock increments during suspend.
+ */
+ static TimeCheck::Duration getDefaultSecondChanceDuration();
/**
* TimeCheck is a RAII object which will notify a callback
@@ -130,7 +140,8 @@
// Returns a string that represents the timeout vs elapsed time,
// and diagnostics if there are any potential issues.
static std::string analyzeTimeouts(
- float timeoutMs, float elapsedSteadyMs, float elapsedSystemMs);
+ float timeoutMs, float secondChanceMs,
+ float elapsedSteadyMs, float elapsedSystemMs);
static TimerThread& getTimeCheckThread();
static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index b763f09..bf2915a 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -141,9 +141,15 @@
cc_defaults {
name: "libaudioflinger_dependencies",
+ header_libs: [
+ "libaudiohal_headers", // required for AudioFlinger
+ ],
+
shared_libs: [
+ "audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
+ "audiopermissioncontroller",
"av-types-aidl-cpp",
"com.android.media.audio-aconfig-cc",
"effect-aidl-cpp",
@@ -177,11 +183,6 @@
"libvibrator",
"packagemanager_aidl-cpp",
],
-
- static_libs: [
- "libaudiospdif",
- "libmedialogservice",
- ],
}
cc_library {
@@ -213,22 +214,21 @@
],
static_libs: [
+ "libaudiospdif",
"libcpustats",
- "libpermission",
+ "libmedialogservice",
],
header_libs: [
- "audiopermissioncontroller_headers",
"audiopolicyservicelocal_headers",
"libaaudio_headers",
- "libaudioclient_headers",
- "libaudiohal_headers",
- "libaudioutils_headers",
"libmedia_headers",
],
export_header_lib_headers: ["audiopolicyservicelocal_headers"],
+ export_include_dirs: ["."],
+
export_shared_lib_headers: [
"libpermission",
],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a17ac58..3ff62a8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -4491,7 +4491,7 @@
// TODO(b/184194057): Use the vibrator information from the vibrator that will be used
// for the HapticGenerator.
const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
- std::move(getDefaultVibratorInfo_l());
+ getDefaultVibratorInfo_l();
if (defaultVibratorInfo) {
// Only set the vibrator info when it is a valid one.
audio_utils::lock_guard _cl(chain->mutex());
@@ -5126,8 +5126,8 @@
} else {
getIAudioFlingerStatistics().event(code, elapsedMs);
}
- }, mediautils::TimeCheck::kDefaultTimeoutDuration,
- mediautils::TimeCheck::kDefaultSecondChanceDuration,
+ }, mediautils::TimeCheck::getDefaultTimeoutDuration(),
+ mediautils::TimeCheck::getDefaultSecondChanceDuration(),
true /* crashOnTimeout */);
return delegate();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 501aed1..dcad0e2 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -339,7 +339,9 @@
const String8& address,
audio_output_flags_t flags) final REQUIRES(mutex());
const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
- getAudioHwDevs_l() const final REQUIRES(mutex()) { return mAudioHwDevs; }
+ getAudioHwDevs_l() const final REQUIRES(mutex(), hardwareMutex()) {
+ return mAudioHwDevs;
+ }
void updateDownStreamPatches_l(const struct audio_patch* patch,
const std::set<audio_io_handle_t>& streams) final REQUIRES(mutex());
void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index feae97e..7cb9329 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -71,10 +71,15 @@
void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
ALOGV("%s", __func__);
+ // Keep a reference on disconnected handle to delay destruction without lock held.
+ std::vector<sp<IAfEffectHandle>> disconnectedHandles{};
audio_utils::lock_guard _l(mutex());
for (auto& effectProxies : mDeviceEffects) {
for (auto& effect : effectProxies.second) {
- effect->onReleasePatch(handle);
+ sp<IAfEffectHandle> disconnectedHandle = effect->onReleasePatch(handle);
+ if (disconnectedHandle != nullptr) {
+ disconnectedHandles.push_back(std::move(disconnectedHandle));
+ }
}
}
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 4da498b..cfd0a5e 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1760,6 +1760,9 @@
const sp<media::IEffectClient>& effectClient,
int32_t priority, bool notifyFramesProcessed)
{
+ if (client == nullptr && effectClient == nullptr) {
+ return sp<InternalEffectHandle>::make(effect, notifyFramesProcessed);
+ }
return sp<EffectHandle>::make(
effect, client, effectClient, priority, notifyFramesProcessed);
}
@@ -1767,12 +1770,14 @@
EffectHandle::EffectHandle(const sp<IAfEffectBase>& effect,
const sp<Client>& client,
const sp<media::IEffectClient>& effectClient,
- int32_t priority, bool notifyFramesProcessed)
- : BnEffect(),
+ int32_t priority, bool notifyFramesProcessed,
+ bool isInternal,
+ audio_utils::MutexOrder mutexOrder)
+ : BnEffect(), mMutex(audio_utils::mutex{mutexOrder}),
mEffect(effect), mEffectClient(media::EffectClientAsyncProxy::makeIfNeeded(effectClient)),
mClient(client), mCblk(nullptr),
mPriority(priority), mHasControl(false), mEnabled(false), mDisconnected(false),
- mNotifyFramesProcessed(notifyFramesProcessed)
+ mNotifyFramesProcessed(notifyFramesProcessed), mIsInternal(isInternal)
{
ALOGV("constructor %p client %p", this, client.get());
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
@@ -1939,7 +1944,7 @@
void EffectHandle::disconnect(bool unpinIfLast)
{
- audio_utils::lock_guard _l(mutex());
+ audio_utils::unique_lock _l(mutex());
ALOGV("disconnect(%s) %p", unpinIfLast ? "true" : "false", this);
if (mDisconnected) {
if (unpinIfLast) {
@@ -1951,11 +1956,19 @@
{
sp<IAfEffectBase> effect = mEffect.promote();
if (effect != 0) {
+ // Unlock e.g. for device effect: may need to acquire AudioFlinger lock
+ // Also Internal Effect Handle would require Proxy lock (and vice versa).
+ if (isInternal()) {
+ _l.unlock();
+ }
if (effect->disconnectHandle(this, unpinIfLast) > 0) {
ALOGW("%s Effect handle %p disconnected after thread destruction",
__func__, this);
}
effect->updatePolicyState();
+ if (isInternal()) {
+ _l.lock();
+ }
}
}
@@ -3544,8 +3557,7 @@
mHalEffect->setDevices({mDevice});
}
}
- *handle = new EffectHandle(mHalEffect, nullptr, nullptr, 0 /*priority*/,
- mNotifyFramesProcessed);
+ *handle = new InternalEffectHandle(mHalEffect, mNotifyFramesProcessed);
status = (*handle)->initCheck();
if (status == OK) {
status = mHalEffect->addHandle((*handle).get());
@@ -3592,15 +3604,16 @@
return status;
}
-void DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
- sp<IAfEffectHandle> effect;
+sp<IAfEffectHandle> DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
+ sp<IAfEffectHandle> disconnectedHandle;
{
audio_utils::lock_guard _l(proxyMutex());
if (mEffectHandles.find(patchHandle) != mEffectHandles.end()) {
- effect = mEffectHandles.at(patchHandle);
+ disconnectedHandle = std::move(mEffectHandles.at(patchHandle));
mEffectHandles.erase(patchHandle);
}
}
+ return disconnectedHandle;
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 5c90176..9ecf89e 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -344,7 +344,8 @@
EffectHandle(const sp<IAfEffectBase>& effect,
const sp<Client>& client,
const sp<media::IEffectClient>& effectClient,
- int32_t priority, bool notifyFramesProcessed);
+ int32_t priority, bool notifyFramesProcessed, bool isInternal = false,
+ audio_utils::MutexOrder mutexOrder = audio_utils::MutexOrder::kEffectHandle_Mutex);
~EffectHandle() override;
status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) final;
@@ -364,6 +365,11 @@
int32_t* _aidl_return) final;
const sp<Client>& client() const final { return mClient; }
+ /**
+ * Checks if the handle is internal, aka created by AudioFlinger for internal needs (e.g.
+ * device effect HAL handle or device effect thread handle).
+ */
+ virtual bool isInternal() const { return mIsInternal; }
sp<android::media::IEffect> asIEffect() final {
return sp<android::media::IEffect>::fromExisting(this);
@@ -401,15 +407,18 @@
void dumpToBuffer(char* buffer, size_t size) const final;
+protected:
+ // protects IEffect method calls
+ mutable audio_utils::mutex mMutex;
private:
DISALLOW_COPY_AND_ASSIGN(EffectHandle);
- audio_utils::mutex& mutex() const RETURN_CAPABILITY(android::audio_utils::EffectHandle_Mutex) {
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(android::audio_utils::EffectHandle_Mutex) {
return mMutex;
}
- // protects IEffect method calls
- mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kEffectHandle_Mutex};
+
const wp<IAfEffectBase> mEffect; // pointer to controlled EffectModule
const sp<media::IEffectClient> mEffectClient; // callback interface for client notifications
/*const*/ sp<Client> mClient; // client for shared memory allocation, see
@@ -425,6 +434,28 @@
bool mDisconnected; // Set to true by disconnect()
const bool mNotifyFramesProcessed; // true if the client callback event
// EVENT_FRAMES_PROCESSED must be generated
+ const bool mIsInternal;
+};
+
+/**
+ * There are 2 types of effects:
+ * -Session Effect: handle is directly called from the client, without AudioFlinger lock.
+ * -Device Effect: a device effect proxy is aggregating a collection of internal effect handles that
+ * controls the same effect added on all audio patches involving the device effect selected port
+ * requested either by a client or by AudioPolicyEffects. These internal effect handles do not have
+ * client. Sequence flow implies a different locking order, hence the lock is specialied.
+ */
+class InternalEffectHandle : public EffectHandle {
+public:
+ InternalEffectHandle(const sp<IAfEffectBase>& effect, bool notifyFramesProcessed) :
+ EffectHandle(effect, /* client= */ nullptr, /* effectClient= */ nullptr,
+ /* priority= */ 0, notifyFramesProcessed, /* isInternal */ true,
+ audio_utils::MutexOrder::kDeviceEffectHandle_Mutex) {}
+
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(android::audio_utils::DeviceEffectHandle_Mutex) {
+ return mMutex;
+ }
};
// the EffectChain class represents a group of effects associated to one audio session.
@@ -762,7 +793,7 @@
status_t onUpdatePatch(audio_patch_handle_t oldPatchHandle, audio_patch_handle_t newPatchHandle,
const IAfPatchPanel::Patch& patch) final;
- void onReleasePatch(audio_patch_handle_t patchHandle) final;
+ sp<IAfEffectHandle> onReleasePatch(audio_patch_handle_t patchHandle) final;
size_t removeEffect(const sp<IAfEffectModule>& effect) final;
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index f1edcfe..3452e94 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -400,7 +400,14 @@
virtual status_t onUpdatePatch(audio_patch_handle_t oldPatchHandle,
audio_patch_handle_t newPatchHandle,
const IAfPatchPanel::Patch& patch) = 0;
- virtual void onReleasePatch(audio_patch_handle_t patchHandle) = 0;
+ /**
+ * Checks (and release) of the effect handle is linked with the given release patch handle.
+ *
+ * @param patchHandle handle of the released patch
+ * @return a reference on the effect handle released if any, nullptr otherwise.
+ * It allows to delay the destruction of the handle.
+ */
+ virtual sp<IAfEffectHandle> onReleasePatch(audio_patch_handle_t patchHandle) = 0;
virtual void dump2(int fd, int spaces) const = 0; // TODO(b/291319101) naming?
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5c0ca5e..ecbd0ae 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1696,7 +1696,7 @@
// TODO(b/184194057): Use the vibrator information from the vibrator that will be used
// for the HapticGenerator.
const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
- std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
+ mAfThreadCallback->getDefaultVibratorInfo_l();
if (defaultVibratorInfo) {
audio_utils::lock_guard _cl(chain->mutex());
// Only set the vibrator info when it is a valid one.
@@ -2917,7 +2917,7 @@
// TODO(b/184194780): Use the vibrator information from the vibrator that will be
// used to play this track.
audio_utils::lock_guard _l(mAfThreadCallback->mutex());
- vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
+ vibratorInfo = mAfThreadCallback->getDefaultVibratorInfo_l();
}
mutex().lock();
track->setHapticScale(hapticScale);
@@ -5093,7 +5093,6 @@
// mPipeSink below
// mNormalSink below
{
- setMasterBalance(afThreadCallback->getMasterBalance_l());
ALOGV("MixerThread() id=%d type=%d", id, type);
ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, "
"mFrameCount=%zu, mNormalFrameCount=%zu",
@@ -5105,6 +5104,8 @@
// The Duplicating thread uses the AudioMixer and delivers data to OutputTracks
// (downstream MixerThreads) in DuplicatingThread::threadLoop_write().
// Do not create or use mFastMixer, mOutputSink, mPipeSink, or mNormalSink.
+ // Balance is *not* set in the DuplicatingThread here (or from AudioFlinger),
+ // as the downstream MixerThreads implement it.
return;
}
// create an NBAIO sink for the HAL output stream, and negotiate
@@ -5264,6 +5265,9 @@
mNormalSink = initFastMixer ? mPipeSink : mOutputSink;
break;
}
+ // setMasterBalance needs to be called after the FastMixer
+ // (if any) is set up, in order to deliver the balance settings to it.
+ setMasterBalance(afThreadCallback->getMasterBalance_l());
}
MixerThread::~MixerThread()
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 654b841..10a77ef 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -379,10 +379,10 @@
return isOutput() ? outDeviceTypes_l() : DeviceTypeSet({inDeviceType_l()});
}
- const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const final {
+ const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const final REQUIRES(mutex()) {
return mOutDeviceTypeAddrs;
}
- const AudioDeviceTypeAddr& inDeviceTypeAddr() const final {
+ const AudioDeviceTypeAddr& inDeviceTypeAddr() const final REQUIRES(mutex()) {
return mInDeviceTypeAddr;
}
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index e91e2a3..deb7345 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -294,8 +294,7 @@
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid,
- bool internal = false) = 0;
+ uid_t uid) = 0;
virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
virtual status_t setMasterMono(bool mono) = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index e8b04ce..051e975 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -42,6 +42,7 @@
"libaudioclient_aidl_conversion",
"libaudiofoundation",
"libaudiopolicy",
+ "libaudioutils",
"libbase",
"libcutils",
"libhidlbase",
@@ -56,9 +57,6 @@
"libmedia",
"libmedia_helper",
],
- static_libs: [
- "libaudioutils",
- ],
header_libs: [
"libaudiopolicycommon",
"libaudiopolicymanager_interface_headers",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 6167f95..e519766 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -47,13 +47,17 @@
if (active) {
// On MMAP IOs, the preferred device is selected by the first client (virtual client
- // created when the mmap stream is opened). This client is never active.
+ // created when the mmap stream is opened). This client is never active and we only
+ // consider the Filter criteria, not the active state.
// On non MMAP IOs, the preferred device is honored only if all active clients have
// a preferred device in which case the first client drives the selection.
if (desc->isMmap()) {
- // The client list is never empty on a MMAP IO
- return devices.getDeviceFromId(
- desc->clientsList(false /*activeOnly*/)[0]->preferredDeviceId());
+ auto matchingClients = desc->clientsList(
+ false /*activeOnly*/, filter, false /*preferredDevice*/);
+ if (matchingClients.empty()) {
+ return nullptr;
+ }
+ return devices.getDeviceFromId(matchingClients[0]->preferredDeviceId());
} else {
auto activeClientsWithRoute =
desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index a596c43..60da405 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -63,6 +63,8 @@
* HW Audio Source.
*/
virtual bool isInternal() const { return false; }
+ virtual bool isCallRx() const { return false; }
+ virtual bool isCallTx() const { return false; }
audio_port_handle_t portId() const { return mPortId; }
uid_t uid() const { return mUid; }
audio_session_t session() const { return mSessionId; };
@@ -236,7 +238,7 @@
const sp<DeviceDescriptor>& srcDevice,
audio_stream_type_t stream, product_strategy_t strategy,
VolumeSource volumeSource,
- bool isInternal);
+ bool isInternal, bool isCallRx, bool isCallTx);
~SourceClientDescriptor() override = default;
@@ -263,6 +265,8 @@
wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
bool isInternal() const override { return mIsInternal; }
+ bool isCallRx() const override { return mIsCallRx; }
+ bool isCallTx() const override { return mIsCallTx; }
using ClientDescriptor::dump;
void dump(String8 *dst, int spaces) const override;
@@ -294,6 +298,8 @@
* requester to prevent rerouting SwOutput involved in raw patches.
*/
bool mIsInternal = false;
+ bool mIsCallRx = false;
+ bool mIsCallTx = false;
};
class SourceClientCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index b92cd70..f7b9b33 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -99,21 +99,20 @@
* @return ioHandle if found, AUDIO_IO_HANDLE_NONE otherwise.
*/
audio_io_handle_t getIoForSession(audio_session_t sessionId,
- const effect_uuid_t *effectType = nullptr) const;
- bool hasOrphansForSession(audio_session_t sessionId) const;
- EffectDescriptorCollection getOrphanEffectsForSession(audio_session_t sessionId) const;
- void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
+ const effect_uuid_t* effectType = nullptr) const;
/**
- * @brief Checks if there is at least one orphan effect with given sessionId and effect type
- * uuid.
+ * @brief Checks if there is at least one orphan effect with given sessionId and optional effect
+ * type uuid.
* @param sessionId Session ID.
- * @param effectType Effect type UUID, the implementation will be same as hasOrphansForSession
- * if null.
+ * @param effectType Optional effect type UUID pointer to effect_uuid_t, nullptr by default.
* @return True if there is an orphan effect for given sessionId and type UUID, false otherwise.
*/
- bool hasOrphanEffectsForSessionAndType(audio_session_t sessionId,
- const effect_uuid_t* effectType) const;
+ bool hasOrphansForSession(audio_session_t sessionId,
+ const effect_uuid_t* effectType = nullptr) const;
+
+ EffectDescriptorCollection getOrphanEffectsForSession(audio_session_t sessionId) const;
+ void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
private:
status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 667c189..ad6977b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -96,12 +96,14 @@
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
audio_attributes_t attributes, const struct audio_port_config &config,
const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
- product_strategy_t strategy, VolumeSource volumeSource, bool isInternal) :
+ product_strategy_t strategy, VolumeSource volumeSource,
+ bool isInternal, bool isCallRx, bool isCallTx) :
TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
{config.sample_rate, config.channel_mask, config.format}, AUDIO_PORT_HANDLE_NONE,
stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
{} /* Sources do not support secondary outputs*/, nullptr),
- mSrcDevice(srcDevice), mIsInternal(isInternal)
+ mSrcDevice(srcDevice), mIsInternal(isInternal),
+ mIsCallRx(isCallRx), mIsCallTx(isCallTx)
{
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 7971b61..090da6c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -210,27 +210,13 @@
}
}
-bool EffectDescriptorCollection::hasOrphansForSession(audio_session_t sessionId) const
-{
+bool EffectDescriptorCollection::hasOrphansForSession(audio_session_t sessionId,
+ const effect_uuid_t* effectType) const {
for (size_t i = 0; i < size(); ++i) {
sp<EffectDescriptor> effect = valueAt(i);
- if (effect->mSession == sessionId && effect->mIsOrphan) {
- return true;
- }
- }
- return false;
-}
-
-bool EffectDescriptorCollection::hasOrphanEffectsForSessionAndType(
- audio_session_t sessionId, const effect_uuid_t* effectType) const {
- if (effectType == nullptr) {
- return hasOrphansForSession(sessionId);
- }
-
- for (size_t i = 0; i < size(); ++i) {
- sp<EffectDescriptor> effect = valueAt(i);
- if (effect->mIsOrphan && effect->mSession == sessionId &&
- memcmp(&effect->mDesc.type, effectType, sizeof(effect_uuid_t)) == 0) {
+ if (effect->mSession == sessionId && effect->mIsOrphan &&
+ (effectType == nullptr ||
+ memcmp(&effect->mDesc.type, effectType, sizeof(effect_uuid_t)) == 0)) {
return true;
}
}
diff --git a/services/audiopolicy/fuzzer/Android.bp b/services/audiopolicy/fuzzer/Android.bp
index 8cee613..30d4403 100644
--- a/services/audiopolicy/fuzzer/Android.bp
+++ b/services/audiopolicy/fuzzer/Android.bp
@@ -28,39 +28,18 @@
cc_fuzz {
name: "audiopolicy_fuzzer",
+ defaults: [
+ "libaudiopolicyservice_dependencies",
+ ],
srcs: [
"audiopolicy_fuzzer.cpp",
],
- include_dirs: [
- "frameworks/av/services/audiopolicy",
- ],
- shared_libs: [
- "android.hardware.audio.common-util",
- "capture_state_listener-aidl-cpp",
- "framework-permission-aidl-cpp",
- "libaudioclient",
- "libaudiofoundation",
- "libaudiopolicy",
- "libaudiopolicycomponents",
- "libaudiopolicymanagerdefault",
- "libbase",
- "libbinder",
- "libcutils",
- "libdl",
- "libhidlbase",
- "liblog",
- "libmedia_helper",
- "libmediametrics",
- "libutils",
- "libxml2",
- ],
static_libs: [
"android.hardware.audio.common@7.0-enums",
],
- header_libs: [
- "libaudiopolicycommon",
- "libaudiopolicyengine_interface_headers",
- "libaudiopolicymanager_interface_headers",
+ include_dirs: [
+ "frameworks/av/services/audiopolicy", // include path outside of libaudiopolicyservice
+ "frameworks/av/services/audiopolicy/engine/interface", // for /tests/AudioPolicyTestManager.h:
],
data: [":audiopolicyfuzzer_configuration_files"],
fuzz_config: {
diff --git a/services/audiopolicy/fuzzer/aidl/Android.bp b/services/audiopolicy/fuzzer/aidl/Android.bp
index a91ecd7..680f76d 100644
--- a/services/audiopolicy/fuzzer/aidl/Android.bp
+++ b/services/audiopolicy/fuzzer/aidl/Android.bp
@@ -23,37 +23,15 @@
cc_defaults {
name: "audiopolicy_aidl_fuzzer_defaults",
shared_libs: [
- "audiopolicy-aidl-cpp",
- "audiopolicy-types-aidl-cpp",
- "framework-permission-aidl-cpp",
- "libactivitymanager_aidl",
- "libaudioclient",
"libaudioflinger",
- "libaudiohal",
- "libaudiopolicy",
- "libaudiopolicymanagerdefault",
"libaudiopolicyservice",
- "libaudioprocessing",
- "libhidlbase",
- "liblog",
- "libmediautils",
- "libnbaio",
- "libnblog",
- "libpowermanager",
- "libvibrator",
- "packagemanager_aidl-cpp",
- ],
- static_libs: [
- "audiopermissioncontroller",
- "libaudiomockhal",
- "libfakeservicemanager",
"libmediaplayerservice",
],
+ static_libs: [
+ "libaudiomockhal",
+ "libfakeservicemanager",
+ ],
header_libs: [
- "libaudioflinger_headers",
- "libaudiohal_headers",
- "libaudiopolicymanager_interface_headers",
- "libbinder_headers",
"libmedia_headers",
],
fuzz_config: {
@@ -78,6 +56,8 @@
"latest_android_hardware_audio_core_ndk_shared",
"latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
+ "libaudioflinger_dependencies",
+ "libaudiopolicyservice_dependencies",
"service_fuzzer_defaults",
],
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 514c5b7..41bf68e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -768,7 +768,7 @@
}
muteWaitMs = setOutputDevices(__func__, mPrimaryOutput, rxDevices, true, delayMs);
} else { // create RX path audio patch
- connectTelephonyRxAudioSource();
+ connectTelephonyRxAudioSource(delayMs);
// If the TX device is on the primary HW module but RX device is
// on other HW module, SinkMetaData of telephony input should handle it
// assuming the device uses audio HAL V5.0 and above
@@ -803,7 +803,7 @@
return false;
}
-void AudioPolicyManager::connectTelephonyRxAudioSource()
+void AudioPolicyManager::connectTelephonyRxAudioSource(uint32_t delayMs)
{
disconnectTelephonyAudioSource(mCallRxSourceClient);
const struct audio_port_config source = {
@@ -813,7 +813,8 @@
const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
- status_t status = startAudioSource(&source, &aa, &portId, 0 /*uid*/, true /*internal*/);
+ status_t status = startAudioSourceInternal(&source, &aa, &portId, 0 /*uid*/,
+ true /*internal*/, true /*isCallRx*/, delayMs);
ALOGE_IF(status != OK, "%s: failed to start audio source (%d)", __func__, status);
mCallRxSourceClient = mAudioSources.valueFor(portId);
ALOGE_IF(mCallRxSourceClient == nullptr,
@@ -850,7 +851,8 @@
srcDevice->toAudioPortConfig(&source);
mCallTxSourceClient = new SourceClientDescriptor(
callTxSourceClientPortId, mUidCached, aa, source, srcDevice, AUDIO_STREAM_PATCH,
- mCommunnicationStrategy, toVolumeSource(aa), true);
+ mCommunnicationStrategy, toVolumeSource(aa), true,
+ false /*isCallRx*/, true /*isCallTx*/);
mCallTxSourceClient->setPreferredDeviceId(sinkDevice->getId());
audio_patch_handle_t patchHandle = AUDIO_PATCH_HANDLE_NONE;
@@ -2143,8 +2145,7 @@
// matching criteria values in priority order for best matching output so far
std::vector<uint32_t> bestMatchCriteria(8, 0);
- const bool hasOrphanHaptic =
- mEffects.hasOrphanEffectsForSessionAndType(sessionId, FX_IID_HAPTICGENERATOR);
+ const bool hasOrphanHaptic = mEffects.hasOrphansForSession(sessionId, FX_IID_HAPTICGENERATOR);
const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(
channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
@@ -5109,7 +5110,7 @@
new SourceClientDescriptor(
portId, uid, attributes, *source, srcDevice, AUDIO_STREAM_PATCH,
mEngine->getProductStrategyForAttributes(attributes), toVolumeSource(attributes),
- true);
+ true, false /*isCallRx*/, false /*isCallTx*/);
sourceDesc->setPreferredDeviceId(sinkDevice->getId());
status_t status =
@@ -5441,7 +5442,7 @@
outputDesc->toAudioPortConfig(&srcMixPortConfig, nullptr);
// for volume control, we may need a valid stream
srcMixPortConfig.ext.mix.usecase.stream =
- (!sourceDesc->isInternal() || isCallTxAudioSource(sourceDesc)) ?
+ (!sourceDesc->isInternal() || sourceDesc->isCallTx()) ?
mEngine->getStreamTypeForAttributes(sourceDesc->attributes()) :
AUDIO_STREAM_PATCH;
patchBuilder.addSource(srcMixPortConfig);
@@ -5779,7 +5780,16 @@
status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid, bool internal)
+ uid_t uid) {
+ return startAudioSourceInternal(source, attributes, portId, uid,
+ false /*internal*/, false /*isCallRx*/, 0 /*delayMs*/);
+}
+
+status_t AudioPolicyManager::startAudioSourceInternal(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_port_handle_t *portId,
+ uid_t uid, bool internal, bool isCallRx,
+ uint32_t delayMs)
{
ALOGV("%s", __FUNCTION__);
*portId = AUDIO_PORT_HANDLE_NONE;
@@ -5812,16 +5822,17 @@
new SourceClientDescriptor(*portId, uid, *attributes, *source, srcDevice,
mEngine->getStreamTypeForAttributes(*attributes),
mEngine->getProductStrategyForAttributes(*attributes),
- toVolumeSource(*attributes), internal);
+ toVolumeSource(*attributes), internal, isCallRx, false);
- status_t status = connectAudioSource(sourceDesc);
+ status_t status = connectAudioSource(sourceDesc, delayMs);
if (status == NO_ERROR) {
mAudioSources.add(*portId, sourceDesc);
}
return status;
}
-status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
+status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc,
+ uint32_t delayMs)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
@@ -5847,7 +5858,7 @@
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
return connectAudioSourceToSink(
- sourceDesc, sinkDevice, patchBuilder.patch(), handle, mUidCached, 0 /*delayMs*/);
+ sourceDesc, sinkDevice, patchBuilder.patch(), handle, mUidCached, delayMs);
}
status_t AudioPolicyManager::stopAudioSource(audio_port_handle_t portId)
@@ -6284,7 +6295,7 @@
// means haptic use cases (either the client channelmask includes haptic bits, or created a
// HapticGenerator effect for this session) are not supported.
return clientHapticChannel == 0 &&
- !mEffects.hasOrphanEffectsForSessionAndType(sessionId, FX_IID_HAPTICGENERATOR);
+ !mEffects.hasOrphansForSession(sessionId, FX_IID_HAPTICGENERATOR);
}
}
@@ -6658,7 +6669,7 @@
status_t status = inputDesc->open(nullptr,
availProfileDevices.itemAt(0),
AUDIO_SOURCE_MIC,
- AUDIO_INPUT_FLAG_NONE,
+ (audio_input_flags_t) inProfile->getFlags(),
&input);
if (status != NO_ERROR) {
ALOGW("%s: Cannot open input stream for device %s for profile %s on hw module %s",
@@ -6973,7 +6984,8 @@
desc = new AudioInputDescriptor(profile, mpClientInterface);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
ALOGV("%s opening input for profile %s", __func__, profile->getTagName().c_str());
- status = desc->open(nullptr, device, AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_NONE, &input);
+ status = desc->open(nullptr, device, AUDIO_SOURCE_MIC,
+ (audio_input_flags_t) profile->getFlags(), &input);
if (status == NO_ERROR) {
const String8& address = String8(device->address().c_str());
@@ -7220,8 +7232,8 @@
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc != nullptr && followsSameRouting(attr, sourceDesc->attributes())
&& sourceDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE
- && !isCallRxAudioSource(sourceDesc) && !sourceDesc->isInternal()) {
- connectAudioSource(sourceDesc);
+ && !sourceDesc->isCallRx() && !sourceDesc->isInternal()) {
+ connectAudioSource(sourceDesc, 0 /*delayMs*/);
}
}
}
@@ -7327,8 +7339,8 @@
}
}
sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
- if (source != nullptr && !isCallRxAudioSource(source) && !source->isInternal()) {
- connectAudioSource(source);
+ if (source != nullptr && !source->isCallRx() && !source->isInternal()) {
+ connectAudioSource(source, 0 /*delayMs*/);
}
}
@@ -8500,7 +8512,7 @@
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->isConnected() && (sourceDesc->srcDevice()->equals(deviceDesc) ||
sourceDesc->sinkDevice()->equals(deviceDesc))
- && !isCallRxAudioSource(sourceDesc)) {
+ && !sourceDesc->isCallRx()) {
disconnectAudioSource(sourceDesc);
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 011e867..1b4f33a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -345,8 +345,7 @@
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid,
- bool internal = false);
+ uid_t uid);
virtual status_t stopAudioSource(audio_port_handle_t portId);
virtual status_t setMasterMono(bool mono);
@@ -705,15 +704,7 @@
void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0,
bool skipDelays = false);
- bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
- return mCallRxSourceClient != nullptr && source == mCallRxSourceClient;
- }
-
- bool isCallTxAudioSource(const sp<SourceClientDescriptor> &source) {
- return mCallTxSourceClient != nullptr && source == mCallTxSourceClient;
- }
-
- void connectTelephonyRxAudioSource();
+ void connectTelephonyRxAudioSource(uint32_t delayMs);
void disconnectTelephonyAudioSource(sp<SourceClientDescriptor> &clientDesc);
@@ -938,7 +929,8 @@
status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
- status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
+ status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc,
+ uint32_t delayMs);
status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t connectAudioSourceToSink(const sp<SourceClientDescriptor>& sourceDesc,
@@ -976,6 +968,13 @@
void checkLeBroadcastRoutes(bool wasUnicastActive,
sp<SwAudioOutputDescriptor> ignoredOutput, uint32_t delayMs);
+ status_t startAudioSourceInternal(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_port_handle_t *portId,
+ uid_t uid,
+ bool internal,
+ bool isCallRx,
+ uint32_t delayMs);
const uid_t mUidCached; // AID_AUDIOSERVER
sp<const AudioPolicyConfig> mConfig;
EngineInstance mEngine; // Audio Policy Engine instance
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 84458f9..e157808 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -11,12 +11,16 @@
cc_defaults {
name: "libaudiopolicyservice_dependencies",
- header_libs: ["audiopolicyservicelocal_headers"],
+ include_dirs: [
+ "frameworks/av/services/audiopolicy", // include path outside of libaudiopolicyservice
+ ],
shared_libs: [
"android.media.audiopolicy-aconfig-cc",
+ "audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
+ "audiopermissioncontroller",
"audiopolicy-aidl-cpp",
"audiopolicy-types-aidl-cpp",
"capture_state_listener-aidl-cpp",
@@ -35,6 +39,7 @@
"libaudioutils",
"libbinder",
"libcutils",
+ "libeffectsconfig",
"libhardware_legacy",
"libheadtracking",
"libheadtracking-binding",
@@ -52,13 +57,6 @@
"packagemanager_aidl-cpp",
"spatializer-aidl-cpp",
],
-
- static_libs: [
- "audio-permission-aidl-cpp",
- "audiopermissioncontroller",
- "libaudiopolicycomponents",
- "libeffectsconfig",
- ],
}
cc_library {
@@ -84,10 +82,6 @@
"frameworks/av/services/audioflinger",
],
- static_libs: [
- "framework-permission-aidl-cpp", // TODO remove when unnnecessary
- ],
-
header_libs: [
"audiopolicyservicelocal_headers",
"libaudiohal_headers",
@@ -97,21 +91,14 @@
"libaudioutils_headers",
],
+ export_include_dirs: ["."],
+
cflags: [
"-Wall",
"-Werror",
"-Wthread-safety",
"-fvisibility=hidden",
],
-
- export_shared_lib_headers: [
- "framework-permission-aidl-cpp",
- "libactivitymanager_aidl",
- "libaudiousecasevalidation",
- "libheadtracking",
- "libheadtracking-binding",
- "libsensorprivacy",
- ],
}
cc_library_headers {
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index cc67481..6144f8c 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -1415,8 +1415,8 @@
} else {
getIAudioPolicyServiceStatistics().event(code, elapsedMs);
}
- }, mediautils::TimeCheck::kDefaultTimeoutDuration,
- mediautils::TimeCheck::kDefaultSecondChanceDuration,
+ }, mediautils::TimeCheck::getDefaultTimeoutDuration(),
+ mediautils::TimeCheck::getDefaultSecondChanceDuration(),
true /* crashOnTimeout */);
switch (code) {
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index dc61115..4006489 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -12,6 +12,7 @@
name: "audiopolicy_tests",
defaults: [
+ "aconfig_lib_cc_shared_link.defaults",
"latest_android_media_audio_common_types_cpp_static",
],
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index acc3b32..516e8f0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -513,7 +513,7 @@
void CameraService::onDeviceStatusChanged(const std::string& cameraId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
- cameraId.c_str(), newHalStatus);
+ cameraId.c_str(), eToI(newHalStatus));
StatusInternal newStatus = mapToInternal(newHalStatus);
@@ -537,7 +537,8 @@
StatusInternal oldStatus = state->getStatus();
if (oldStatus == newStatus) {
- ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
+ ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__,
+ eToI(newStatus));
return;
}
@@ -580,7 +581,7 @@
const std::string& physicalId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
- __FUNCTION__, id.c_str(), physicalId.c_str(), newHalStatus);
+ __FUNCTION__, id.c_str(), physicalId.c_str(), eToI(newHalStatus));
StatusInternal newStatus = mapToInternal(newHalStatus);
@@ -596,7 +597,7 @@
if (logicalCameraStatus != StatusInternal::PRESENT &&
logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
- __FUNCTION__, physicalId.c_str(), newHalStatus, logicalCameraStatus);
+ __FUNCTION__, physicalId.c_str(), eToI(newHalStatus), eToI(logicalCameraStatus));
return;
}
@@ -688,7 +689,7 @@
void CameraService::onTorchStatusChangedLocked(const std::string& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
- __FUNCTION__, cameraId.c_str(), newStatus);
+ __FUNCTION__, cameraId.c_str(), eToI(newStatus));
TorchModeStatus status;
status_t res = getTorchStatusLocked(cameraId, &status);
@@ -1536,7 +1537,7 @@
s << ", " << std::to_string(i);
}
}
- return std::move(s.str());
+ return s.str();
}
int32_t CameraService::mapToInterface(TorchModeStatus status) {
@@ -1552,7 +1553,7 @@
serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
break;
default:
- ALOGW("Unknown new flash status: %d", status);
+ ALOGW("Unknown new flash status: %d", eToI(status));
}
return serviceStatus;
}
@@ -1570,7 +1571,7 @@
serviceStatus = StatusInternal::ENUMERATING;
break;
default:
- ALOGW("Unknown new HAL device status: %d", status);
+ ALOGW("Unknown new HAL device status: %d", eToI(status));
}
return serviceStatus;
}
@@ -1594,7 +1595,7 @@
serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
break;
default:
- ALOGW("Unknown new internal device status: %d", status);
+ ALOGW("Unknown new internal device status: %d", eToI(status));
}
return serviceStatus;
}
@@ -5171,7 +5172,7 @@
}
if (hasAny) ret << "\n";
ret << "]\n";
- return std::move(ret.str());
+ return ret.str();
}
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
@@ -5777,7 +5778,7 @@
}
ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
- cameraId.c_str(), oldStatus, status);
+ cameraId.c_str(), eToI(oldStatus), eToI(status));
if (oldStatus == StatusInternal::NOT_PRESENT &&
(status != StatusInternal::PRESENT &&
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index d23566c..1ec5072 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -26,6 +26,7 @@
#include <device3/Camera3StreamInterface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <mediautils/AImageReaderUtils.h>
+#include "utils/Utils.h"
namespace android::hardware::cameraservice::utils::conversion::aidl {
@@ -347,8 +348,8 @@
// Ensure the vendor ID are the same before attempting
// anything else. If vendor IDs differ we cannot safely copy the characteristics.
if (from.getVendorId() != to->getVendorId()) {
- ALOGE("%s: Incompatible CameraMetadata objects. Vendor IDs differ. From: %lu; To: %lu",
- __FUNCTION__, from.getVendorId(), to->getVendorId());
+ ALOGE("%s: Incompatible CameraMetadata objects. Vendor IDs differ. From: %" PRIu64
+ "; To: %" PRIu64, __FUNCTION__, from.getVendorId(), to->getVendorId());
return BAD_VALUE;
}
@@ -364,7 +365,7 @@
for (size_t i = 0; i < get_camera_metadata_entry_count(src); i++) {
int ret = get_camera_metadata_ro_entry(src, i, &entry);
if (ret != OK) {
- ALOGE("%s: Could not fetch entry at index %lu. Error: %d", __FUNCTION__, i, ret);
+ ALOGE("%s: Could not fetch entry at index %zu. Error: %d", __FUNCTION__, i, ret);
from.unlock(src);
return BAD_VALUE;
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 61577e4..0d89b3e 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -420,7 +420,7 @@
result << " none\n";
}
- std::string resultStr = std::move(result.str());
+ std::string resultStr = result.str();
write(fd, resultStr.c_str(), resultStr.size());
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index c995cbe..ea4f6fd 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -40,6 +40,7 @@
#include "common/CameraDeviceBase.h"
#include "utils/ExifUtils.h"
#include "utils/SessionConfigurationUtils.h"
+#include "utils/Utils.h"
#include "HeicEncoderInfoManager.h"
#include "HeicCompositeStream.h"
@@ -1464,7 +1465,7 @@
const uint8_t *header = appSegmentBuffer + (maxSize - sizeof(CameraBlob));
const CameraBlob *blob = (const CameraBlob*)(header);
if (blob->blobId != CameraBlobId::JPEG_APP_SEGMENTS) {
- ALOGE("%s: Invalid EXIF blobId %d", __FUNCTION__, blob->blobId);
+ ALOGE("%s: Invalid EXIF blobId %d", __FUNCTION__, eToI(blob->blobId));
return 0;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 6416c11..2440c37 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -51,6 +51,7 @@
#include "api2/HeicCompositeStream.h"
#include "device3/ZoomRatioMapper.h"
+#include "utils/Utils.h"
namespace android {
@@ -92,7 +93,7 @@
case TorchModeStatus::AVAILABLE_ON:
return "AVAILABLE_ON";
}
- ALOGW("Unexpected HAL torch mode status code %d", s);
+ ALOGW("Unexpected HAL torch mode status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
@@ -105,7 +106,7 @@
case CameraDeviceStatus::ENUMERATING:
return "ENUMERATING";
}
- ALOGW("Unexpected HAL device status code %d", s);
+ ALOGW("Unexpected HAL device status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
@@ -2279,7 +2280,7 @@
return tryToInitializeAidlProviderLocked(removedAidlProviderName,
providerInfo);
default:
- ALOGE("%s Unsupported Transport %d", __FUNCTION__, providerTransport);
+ ALOGE("%s Unsupported Transport %d", __FUNCTION__, eToI(providerTransport));
}
}
}
@@ -2366,7 +2367,7 @@
}
break;
default:
- ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
+ ALOGE("%s Invalid transport %d", __FUNCTION__, eToI(transport));
return BAD_VALUE;
}
@@ -2712,7 +2713,7 @@
}
if (!known) {
ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
+ mProviderName.c_str(), cameraDeviceName.c_str(), eToI(newStatus));
return;
}
// no lock needed since listener is set up only once during
diff --git a/services/camera/libcameraservice/common/HalConversionsTemplated.h b/services/camera/libcameraservice/common/HalConversionsTemplated.h
index 96a715c..c586062 100644
--- a/services/camera/libcameraservice/common/HalConversionsTemplated.h
+++ b/services/camera/libcameraservice/common/HalConversionsTemplated.h
@@ -19,6 +19,7 @@
#include "common/CameraProviderManager.h"
#include <device3/Camera3StreamInterface.h>
+#include <utils/Utils.h>
namespace android {
@@ -48,7 +49,7 @@
case HalCameraDeviceStatus::ENUMERATING:
return CameraDeviceStatus::ENUMERATING;
}
- ALOGW("Unexpectedcamera device status code %d", s);
+ ALOGW("Unexpectedcamera device status code %d", eToI(s));
return CameraDeviceStatus::NOT_PRESENT;
}
@@ -74,7 +75,7 @@
case HalTorchModeStatus::AVAILABLE_ON:
return TorchModeStatus::AVAILABLE_ON;
}
- ALOGW("Unexpectedcamera torch mode status code %d", s);
+ ALOGW("Unexpectedcamera torch mode status code %d", eToI(s));
return TorchModeStatus::NOT_AVAILABLE;
}
@@ -88,7 +89,7 @@
case HalCameraDeviceStatus::ENUMERATING:
return "ENUMERATING";
}
- ALOGW("Unexpected HAL device status code %d", s);
+ ALOGW("Unexpected HAL device status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index 1e546fb..40800d9 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -26,6 +26,7 @@
#include "device3/ZoomRatioMapper.h"
#include <utils/SessionConfigurationUtilsHidl.h>
#include <utils/Trace.h>
+#include <utils/Utils.h>
#include <android/hardware/camera/device/3.7/ICameraDevice.h>
@@ -69,7 +70,7 @@
case Status::INTERNAL_ERROR:
return INVALID_OPERATION;
}
- ALOGW("Unexpected HAL status code %d", s);
+ ALOGW("Unexpected HAL status code %d", eToI(s));
return INVALID_OPERATION;
}
@@ -111,7 +112,7 @@
case Status::INTERNAL_ERROR:
return "INTERNAL_ERROR";
}
- ALOGW("Unexpected HAL status code %d", s);
+ ALOGW("Unexpected HAL status code %d", eToI(s));
return "UNKNOWN_ERROR";
}
@@ -591,7 +592,7 @@
}
if (status != Status::OK) {
ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
- __FUNCTION__, id.c_str(), statusToString(status), status);
+ __FUNCTION__, id.c_str(), statusToString(status), eToI(status));
return;
}
@@ -770,7 +771,7 @@
if (status != Status::OK) {
ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
__FUNCTION__, id.c_str(), mId.c_str(),
- statusToString(status), status);
+ statusToString(status), eToI(status));
return;
}
@@ -928,7 +929,7 @@
res = INVALID_OPERATION;
break;
default:
- ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, callStatus);
+ ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, eToI(callStatus));
res = UNKNOWN_ERROR;
}
} else {
@@ -1076,7 +1077,7 @@
break;
default:
ALOGE("%s: Session configuration query failed: %d", __FUNCTION__,
- callStatus);
+ eToI(callStatus));
res = UNKNOWN_ERROR;
}
} else {
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index c42e51a..65fee7d 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -485,7 +485,7 @@
streamId, bufferCount);
}
}
- std::string linesStr = std::move(lines.str());
+ std::string linesStr = lines.str();
write(fd, linesStr.c_str(), linesStr.size());
}
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 22d2716..61c5a3b 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -104,7 +104,7 @@
lines << fmt::sprintf(" Total buffers: %zu, currently dequeued: %zu, "
"currently cached: %zu\n", mTotalBufferCount, mHandoutTotalBufferCount,
mCachedOutputBufferCount);
- std::string linesStr = std::move(lines.str());
+ std::string linesStr = lines.str();
write(fd, linesStr.c_str(), linesStr.size());
Camera3Stream::dump(fd, args);
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 9dacaf6..09299e6 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -56,6 +56,7 @@
#include "device3/hidl/HidlCamera3OfflineSession.h"
#include "utils/SessionConfigurationUtilsHidl.h"
#include "utils/TraceHFR.h"
+#include "utils/Utils.h"
#include "../../common/hidl/HidlProviderInfo.h"
#include "HidlCamera3Device.h"
@@ -881,7 +882,7 @@
ret = true;
break;
default:
- ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
+ ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, eToI(callStatus));
ret = true;
}
} else {
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index d5e3790..85bca6f 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -268,6 +268,12 @@
const auto& gbps = config.getGraphicBufferProducers();
int32_t width = 0, height = 0;
if (gbps.size() > 0) {
+ if (gbps[0] == nullptr) {
+ ALOGE("%s: Failed to query size due to abandoned surface.",
+ __FUNCTION__);
+ return CameraFeatureCombinationStats::CAMERA_FEATURE_UNKNOWN;
+ }
+
sp<Surface> surface = new Surface(gbps[0], /*useAsync*/false);
ANativeWindow *anw = surface.get();
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index cfa1815..9986a84 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -23,6 +23,7 @@
#include "device3/aidl/AidlCamera3Device.h"
#include "device3/hidl/HidlCamera3Device.h"
#include "device3/Camera3OutputStream.h"
+#include "utils/Utils.h"
using android::camera3::OutputStreamInfo;
using android::hardware::camera2::ICameraDeviceUser;
@@ -48,16 +49,16 @@
hidl.streams.resize(aidl.streams.size());
size_t i = 0;
for (const auto &stream : aidl.streams) {
- if (static_cast<int>(stream.dynamicRangeProfile) !=
+ if (eToI(stream.dynamicRangeProfile) !=
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
ALOGE("%s Dynamic range profile %" PRId64 " not supported by HIDL", __FUNCTION__,
- stream.dynamicRangeProfile);
+ eToI(stream.dynamicRangeProfile));
return BAD_VALUE;
}
- if (static_cast<int>(stream.useCase) != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ if (eToI(stream.useCase) != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
ALOGE("%s Stream use case %" PRId64 "not supported by HIDL", __FUNCTION__,
- stream.useCase);
+ eToI(stream.useCase));
return BAD_VALUE;
}
diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp
index 38de93a..5258c0e 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.cpp
+++ b/services/camera/libcameraservice/utils/TagMonitor.cpp
@@ -384,7 +384,7 @@
}
returnStr << "]\n";
}
- return std::move(returnStr.str());
+ return returnStr.str();
}
template<typename T>
diff --git a/services/camera/libcameraservice/utils/Utils.h b/services/camera/libcameraservice/utils/Utils.h
index 4e90871..0eb5e2c 100644
--- a/services/camera/libcameraservice/utils/Utils.h
+++ b/services/camera/libcameraservice/utils/Utils.h
@@ -19,10 +19,21 @@
#include <sched.h>
#include <unistd.h>
+#include <type_traits>
namespace android {
/**
+ * Magically convert an enum to its underlying integer type, mostly so they can be
+ * printed with printf-style formatters without warnings.
+ * Backport of C++23 std::to_underlying()
+ */
+template<typename Enum>
+constexpr std::underlying_type_t<Enum> eToI(Enum val) {
+ return static_cast<std::underlying_type_t<Enum>>(val);
+}
+
+/**
* As of Android V, ro.board.api_level returns the year and month of release (ex. 202404)
* instead of release SDK version. This function maps year/month format back to release
* SDK version.
diff --git a/services/camera/virtualcamera/util/JpegUtil.h b/services/camera/virtualcamera/util/JpegUtil.h
index 184dd56..0a8df90 100644
--- a/services/camera/virtualcamera/util/JpegUtil.h
+++ b/services/camera/virtualcamera/util/JpegUtil.h
@@ -18,6 +18,7 @@
#define ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
#include <optional>
+#include <vector>
#include "android/hardware_buffer.h"
#include "util/Util.h"
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index fdb56e5..7a4c3ad 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -29,6 +29,8 @@
"packagemanager_aidl-cpp",
],
+ export_include_dirs: ["."],
+
cflags: [
"-Wall",
"-Werror",
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index a8a1de1..8b3711c 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -821,7 +821,7 @@
metricsLog += getAppsPixelCount(mProcessPixelsMap);
metricsLog += getAppsCodecUsageMetrics(mProcessConcurrentCodecsMap);
- return std::move(metricsLog);
+ return metricsLog;
}
} // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
index 679ab13..49f68e9 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
@@ -94,7 +94,7 @@
str.append("\n");
}
- return std::move(str);
+ return str;
}
bool ResourceList::operator==(const ResourceList& rhs) const {
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index e3601a1..67b319f 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -84,6 +84,7 @@
shared_libs: [
"aaudio-aidl-cpp",
"com.android.media.aaudio-aconfig-cc",
+ "com.android.media.aaudio-aconfig-cc",
"framework-permission-aidl-cpp",
"libaaudio_internal",
"libaudioclient",
@@ -157,6 +158,8 @@
"frameworks/av/media/libnbaio/include_mono",
],
+ export_include_dirs: ["."],
+
tidy: true,
tidy_checks: tidy_errors,
tidy_checks_as_errors: tidy_errors,