Merge "Camera: Pass metadataGetter from CameraDeviceClient" into tm-dev
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index f370f5e..3965bcc 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -49,7 +49,7 @@
#define INPUT_DUMP_EXT "m2v"
#define GENERATE_FILE_NAMES() { \
nsecs_t now = systemTime(); \
- sprintf(mInFile, "%s_%" PRId64 ".%s",
+ sprintf(mInFile, "%s_%" PRId64 ".%s", \
INPUT_DUMP_PATH, now, \
INPUT_DUMP_EXT); \
}
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 55b1ed7..b3f7f25 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -216,7 +216,8 @@
sp<AMessage> format = new AMessage;
status_t err = convertMetaDataToMessage(trackMeta, &format);
if (err != OK) {
- format = NULL;
+ ALOGE("getImageInternal: convertMetaDataToMessage() failed, unable to extract image");
+ return NULL;
}
uint32_t bitDepth = 8;
@@ -400,7 +401,8 @@
sp<AMessage> format = new AMessage;
status_t err = convertMetaDataToMessage(trackMeta, &format);
if (err != OK) {
- format = NULL;
+ ALOGE("getFrameInternal: convertMetaDataToMessage() failed, unable to extract frame");
+ return NULL;
}
Vector<AString> matchingCodecs;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2a75342..5a27362 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -186,9 +186,12 @@
// XXX suppress until we get our representation right
static bool kEmitHistogram = false;
+static int64_t getId(IResourceManagerClient const * client) {
+ return (int64_t) client;
+}
static int64_t getId(const std::shared_ptr<IResourceManagerClient> &client) {
- return (int64_t) client.get();
+ return getId(client.get());
}
static bool isResourceError(status_t err) {
@@ -205,12 +208,20 @@
////////////////////////////////////////////////////////////////////////////////
struct ResourceManagerClient : public BnResourceManagerClient {
- explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
+ explicit ResourceManagerClient(MediaCodec* codec, int32_t pid) :
+ mMediaCodec(codec), mPid(pid) {}
Status reclaimResource(bool* _aidl_return) override {
sp<MediaCodec> codec = mMediaCodec.promote();
if (codec == NULL) {
- // codec is already gone.
+ // Codec is already gone, so remove the resources as well
+ ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
+ std::shared_ptr<IResourceManagerService> service =
+ IResourceManagerService::fromBinder(binder);
+ if (service == nullptr) {
+ ALOGW("MediaCodec::ResourceManagerClient unable to find ResourceManagerService");
+ }
+ service->removeClient(mPid, getId(this));
*_aidl_return = true;
return Status::ok();
}
@@ -247,6 +258,7 @@
private:
wp<MediaCodec> mMediaCodec;
+ int32_t mPid;
DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
};
@@ -820,7 +832,7 @@
mGetCodecBase(getCodecBase),
mGetCodecInfo(getCodecInfo) {
mResourceManagerProxy = new ResourceManagerServiceProxy(pid, uid,
- ::ndk::SharedRefBase::make<ResourceManagerClient>(this));
+ ::ndk::SharedRefBase::make<ResourceManagerClient>(this, pid));
if (!mGetCodecBase) {
mGetCodecBase = [](const AString &name, const char *owner) {
return GetCodecBase(name, owner);
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index d1655ef..713b0ac 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -125,7 +125,7 @@
void SourceClientCollection::dump(String8 *dst) const
{
- dst->append("\n Audio sources (%zu):\n", size());
+ dst->appendFormat("\n Audio sources (%zu):\n", size());
for (size_t i = 0; i < size(); i++) {
const std::string prefix = base::StringPrintf(" %zu. ", i + 1);
dst->appendFormat("%s", prefix.c_str());
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fdbbe1b..49a0dde 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -287,9 +287,12 @@
sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
// close unused outputs after device disconnection or direct outputs that have
// been opened by checkOutputsForDevice() to query dynamic parameters
+ // "outputs" vector never contains duplicated outputs
if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)
|| (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
- (desc->mDirectOpenCount == 0))) {
+ (desc->mDirectOpenCount == 0))
+ || (((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) &&
+ !isOutputOnlyAvailableRouteToSomeDevice(desc))) {
clearAudioSourcesForOutput(output);
closeOutput(output);
}
@@ -5361,6 +5364,29 @@
}
}
+
+bool AudioPolicyManager::isOutputOnlyAvailableRouteToSomeDevice(
+ const sp<SwAudioOutputDescriptor>& outputDesc) {
+ if (outputDesc->isDuplicated()) {
+ return false;
+ }
+ DeviceVector devices = outputDesc->supportedDevices();
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (desc == outputDesc || desc->isDuplicated()) {
+ continue;
+ }
+ DeviceVector sharedDevices = desc->filterSupportedDevices(devices);
+ if (!sharedDevices.isEmpty()
+ && (desc->devicesSupportEncodedFormats(sharedDevices.types())
+ == outputDesc->devicesSupportEncodedFormats(sharedDevices.types()))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
status_t AudioPolicyManager::getSpatializerOutput(const audio_config_base_t *mixerConfig,
const audio_attributes_t *attr,
audio_io_handle_t *output) {
@@ -5376,80 +5402,67 @@
}
if (!canBeSpatializedInt(
attr, configPtr, devicesTypeAddress)) {
- ALOGW("%s provided attributes or mixer config cannot be spatialized", __func__);
+ ALOGV("%s provided attributes or mixer config cannot be spatialized", __func__);
return BAD_VALUE;
}
sp<IOProfile> profile =
getSpatializerOutputProfile(configPtr, devicesTypeAddress);
if (profile == nullptr) {
- ALOGW("%s no suitable output profile for provided attributes or mixer config", __func__);
+ ALOGV("%s no suitable output profile for provided attributes or mixer config", __func__);
return BAD_VALUE;
}
- if (mSpatializerOutput != nullptr && mSpatializerOutput->mProfile == profile
- && configPtr != nullptr
- && configPtr->channel_mask == mSpatializerOutput->mMixerChannelMask) {
- *output = mSpatializerOutput->mIoHandle;
- ALOGV("%s returns current spatializer output %d", __func__, *output);
- return NO_ERROR;
- }
- mSpatializerOutput.clear();
+ std::vector<sp<SwAudioOutputDescriptor>> spatializerOutputs;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && desc->mProfile == profile) {
- ALOGV("%s found output %d for spatializer profile", __func__, desc->mIoHandle);
- mSpatializerOutput = desc;
- break;
+ if (!desc->isDuplicated()
+ && (desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
+ spatializerOutputs.push_back(desc);
+ ALOGV("%s adding opened spatializer Output %d", __func__, desc->mIoHandle);
}
}
- if (mSpatializerOutput == nullptr) {
- ALOGW("%s no opened spatializer output for profile %s",
- __func__, profile->getName().c_str());
- return BAD_VALUE;
+ mSpatializerOutput.clear();
+ bool outputsChanged = false;
+ for (const auto& desc : spatializerOutputs) {
+ if (desc->mProfile == profile
+ && (configPtr == nullptr
+ || configPtr->channel_mask == desc->mMixerChannelMask)) {
+ mSpatializerOutput = desc;
+ ALOGV("%s reusing current spatializer output %d", __func__, desc->mIoHandle);
+ } else {
+ ALOGV("%s closing spatializerOutput output %d to match channel mask %#x"
+ " and devices %s", __func__, desc->mIoHandle,
+ configPtr != nullptr ? configPtr->channel_mask : 0,
+ devices.toString().c_str());
+ closeOutput(desc->mIoHandle);
+ outputsChanged = true;
+ }
}
- if (configPtr != nullptr
- && configPtr->channel_mask != mSpatializerOutput->mMixerChannelMask) {
- audio_config_base_t savedMixerConfig = {
- .sample_rate = mSpatializerOutput->getSamplingRate(),
- .format = mSpatializerOutput->getFormat(),
- .channel_mask = mSpatializerOutput->mMixerChannelMask,
- };
- DeviceVector savedDevices = mSpatializerOutput->devices();
-
- ALOGV("%s reopening spatializer output to match channel mask %#x (current mask %#x)",
- __func__, configPtr->channel_mask, mSpatializerOutput->mMixerChannelMask);
-
- closeOutput(mSpatializerOutput->mIoHandle);
- //from now on mSpatializerOutput is null
-
+ if (mSpatializerOutput == nullptr) {
sp<SwAudioOutputDescriptor> desc =
openOutputWithProfileAndDevice(profile, devices, mixerConfig);
- if (desc == nullptr) {
- // re open the spatializer output with previous channel mask
- desc = openOutputWithProfileAndDevice(profile, savedDevices, &savedMixerConfig);
- if (desc == nullptr) {
- ALOGE("%s failed to restore mSpatializerOutput with previous config", __func__);
- } else {
- mSpatializerOutput = desc;
- }
- mPreviousOutputs = mOutputs;
- mpClientInterface->onAudioPortListUpdate();
- *output = AUDIO_IO_HANDLE_NONE;
- ALOGW("%s could not open spatializer output with requested config", __func__);
- return BAD_VALUE;
+ if (desc != nullptr) {
+ mSpatializerOutput = desc;
+ outputsChanged = true;
}
- mSpatializerOutput = desc;
- mPreviousOutputs = mOutputs;
- mpClientInterface->onAudioPortListUpdate();
}
checkVirtualizerClientRoutes();
+ if (outputsChanged) {
+ mPreviousOutputs = mOutputs;
+ mpClientInterface->onAudioPortListUpdate();
+ }
+
+ if (mSpatializerOutput == nullptr) {
+ ALOGV("%s could not open spatializer output with requested config", __func__);
+ return BAD_VALUE;
+ }
*output = mSpatializerOutput->mIoHandle;
- ALOGV("%s returns new spatializer output %d", __func__, *output);
- return NO_ERROR;
+ ALOGV("%s returning new spatializer output %d", __func__, *output);
+ return OK;
}
status_t AudioPolicyManager::releaseSpatializerOutput(audio_io_handle_t output) {
@@ -5460,9 +5473,12 @@
return BAD_VALUE;
}
- mSpatializerOutput.clear();
-
- checkVirtualizerClientRoutes();
+ if (!isOutputOnlyAvailableRouteToSomeDevice(mSpatializerOutput)) {
+ ALOGV("%s closing spatializer output %d", __func__, mSpatializerOutput->mIoHandle);
+ closeOutput(mSpatializerOutput->mIoHandle);
+ //from now on mSpatializerOutput is null
+ checkVirtualizerClientRoutes();
+ }
return NO_ERROR;
}
@@ -5739,6 +5755,21 @@
inputDesc->close();
}
}
+
+ // Check if spatializer outputs can be closed until used.
+ // mOutputs vector never contains duplicated outputs at this point.
+ std::vector<audio_io_handle_t> outputsClosed;
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if ((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
+ && !isOutputOnlyAvailableRouteToSomeDevice(desc)) {
+ outputsClosed.push_back(desc->mIoHandle);
+ desc->close();
+ }
+ }
+ for (auto output : outputsClosed) {
+ removeOutput(output);
+ }
}
void AudioPolicyManager::addOutput(audio_io_handle_t output,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 715ee6d..0d9b5bf 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1097,6 +1097,16 @@
void checkVirtualizerClientRoutes();
/**
+ * @brief Returns true if at least one device can only be reached via the output passed
+ * as argument. Always returns false for duplicated outputs.
+ * This can be used to decide if an output can be closed without forbidding
+ * playback to any given device.
+ * @param outputDesc the output to consider
+ * @return true if at least one device can only be reached via the output.
+ */
+ bool isOutputOnlyAvailableRouteToSomeDevice(const sp<SwAudioOutputDescriptor>& outputDesc);
+
+ /**
* @brief getInputForDevice selects an input handle for a given input device and
* requester context
* @param device to be used by requester, selected by policy mix rules or engine
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index e0584df..b4610bc 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -732,6 +732,7 @@
return true;
}
+ int failedClientPid = -1;
{
Mutex::Autolock lock(mLock);
bool found = false;
@@ -746,11 +747,14 @@
}
}
if (found) {
+ failedClientPid = mMap.keyAt(i);
break;
}
}
- if (!found) {
- ALOGV("didn't find failed client");
+ if (found) {
+ ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
+ } else {
+ ALOGW("Failed to reclaim resources from unlocateable client");
}
}