Merge "stagefright: distinguish HAL name from name in MediaCodecInfo" into main
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 1a6e5e8..5acd35c 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -737,9 +737,10 @@
}
printf(" owner: \"%s\"\n", info->getOwnerName());
+ printf(" hal name: \"%s\"\n", info->getHalName());
printf(" rank: %u\n", info->getRank());
} else {
- printf(" aliases, attributes, owner, rank: see above\n");
+ printf(" aliases, attributes, owner, hal name, rank: see above\n");
}
{
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 5578ead..99f0f53 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1043,11 +1043,12 @@
mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
return;
}
- ALOGD("allocate(%s)", codecInfo->getCodecName());
mClientListener.reset(new ClientListener(this));
AString componentName = codecInfo->getCodecName();
+ AString halName = codecInfo->getHalName();
std::shared_ptr<Codec2Client> client;
+ ALOGD("allocate(%s)", componentName.c_str());
// set up preferred component store to access vendor store parameters
client = Codec2Client::CreateFromService("default");
@@ -1059,12 +1060,12 @@
std::shared_ptr<Codec2Client::Component> comp;
c2_status_t status = Codec2Client::CreateComponentByName(
- componentName.c_str(),
+ halName.c_str(),
mClientListener,
&comp,
&client);
if (status != C2_OK) {
- ALOGE("Failed Create component: %s, error=%d", componentName.c_str(), status);
+ ALOGE("Failed Create component: %s, error=%d", halName.c_str(), status);
Mutexed<State>::Locked state(mState);
state->set(RELEASED);
state.unlock();
@@ -1072,7 +1073,7 @@
state.lock();
return;
}
- ALOGI("Created component [%s]", componentName.c_str());
+ ALOGI("Created component [%s] for [%s]", halName.c_str(), componentName.c_str());
mChannel->setComponent(comp);
auto setAllocated = [this, comp, client] {
Mutexed<State>::Locked state(mState);
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 3834278..db83a42 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -22,6 +22,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include "media/stagefright/foundation/AString.h"
#include <binder/Parcel.h>
namespace android {
@@ -185,6 +186,10 @@
return mName.c_str();
}
+const char *MediaCodecInfo::getHalName() const {
+ return mHalName.c_str();
+}
+
const char *MediaCodecInfo::getOwnerName() const {
return mOwner.c_str();
}
@@ -193,11 +198,13 @@
sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
sMaxSupportedInstances = parcel.readInt32();
AString name = AString::FromParcel(parcel);
+ AString halName = AString::FromParcel(parcel);
AString owner = AString::FromParcel(parcel);
Attributes attributes = static_cast<Attributes>(parcel.readInt32());
uint32_t rank = parcel.readUint32();
sp<MediaCodecInfo> info = new MediaCodecInfo;
info->mName = name;
+ info->mHalName = halName;
info->mOwner = owner;
info->mAttributes = attributes;
info->mRank = rank;
@@ -226,6 +233,7 @@
status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
parcel->writeInt32(sMaxSupportedInstances);
mName.writeToParcel(parcel);
+ mHalName.writeToParcel(parcel);
mOwner.writeToParcel(parcel);
parcel->writeInt32(mAttributes);
parcel->writeUint32(mRank);
@@ -278,6 +286,9 @@
void MediaCodecInfoWriter::setName(const char* name) {
mInfo->mName = name;
+ // Upon creation, we use the same name for HAL and info and
+ // only distinguish them during collision resolution.
+ mInfo->mHalName = name;
}
void MediaCodecInfoWriter::addAlias(const char* name) {
@@ -331,6 +342,24 @@
}
}
+sp<MediaCodecInfo> MediaCodecInfo::splitOutType(const char *mediaType,
+ const char *newName) const {
+ sp<MediaCodecInfo> newInfo = new MediaCodecInfo;
+ newInfo->mName = newName;
+ newInfo->mHalName = mHalName;
+ newInfo->mOwner = mOwner;
+ newInfo->mAttributes = mAttributes;
+ newInfo->mRank = mRank;
+ newInfo->mAliases = mAliases;
+ // allow an alias from the (old) HAL name. If there is a collision, this will be ignored.
+ newInfo->mAliases.add(mHalName);
+
+ // note: mediaType is always a supported type. valueAt() will abort otherwise.
+ newInfo->mCaps.add(AString(mediaType), mCaps.valueAt(getCapabilityIndex(mediaType)));
+ newInfo->mCodecCaps.add(AString(mediaType), mCodecCaps.valueAt(getCodecCapIndex(mediaType)));
+ return newInfo;
+}
+
// static
std::shared_ptr<CodecCapabilities> MediaCodecInfoWriter::BuildCodecCapabilities(
const char *mediaType, sp<MediaCodecInfo::Capabilities> caps, bool isEncoder,
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index 60e383a..4d74a67 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -193,7 +193,11 @@
void getSupportedMediaTypes(Vector<AString> *mediaTypes) const;
const sp<Capabilities> getCapabilitiesFor(const char *mediaType) const;
const std::shared_ptr<CodecCapabilities> getCodecCapsFor(const char *mediaType) const;
+
+ /// returns the codec name used by this info
const char *getCodecName() const;
+ /// returns the codec name as used by the HAL
+ const char *getHalName() const;
/**
* Returns a vector containing alternate names for the codec.
@@ -229,14 +233,24 @@
static sp<MediaCodecInfo> FromParcel(const Parcel &parcel);
status_t writeToParcel(Parcel *parcel) const;
+ /**
+ * Create a copy of this MediaCodecInfo supporting a single media type.
+ *
+ * \param mediaType the media type for the new MediaCodecInfo. This must be
+ * one of the media types supported by this MediaCodecInfo.
+ * \param newName the new codec name for the new MediaCodecInfo.
+ */
+ sp<MediaCodecInfo> splitOutType(const char *mediaType, const char *newName) const;
+
private:
/**
* Max supported instances setting from MediaCodecList global setting.
*/
static int32_t sMaxSupportedInstances;
- AString mName;
- AString mOwner;
+ AString mName; // codec name for this info
+ AString mHalName; // codec name at the HAL level
+ AString mOwner; // owning HAL name
Attributes mAttributes;
KeyedVector<AString, sp<Capabilities> > mCaps;
KeyedVector<AString, std::shared_ptr<CodecCapabilities>> mCodecCaps;
@@ -283,7 +297,13 @@
/**
* Set the name of the codec.
*
- * @param name The new name.
+ * This sets both the name used internally and the HAL name, as during
+ * creation, they are the same. A new internal name will only be created
+ * during name collision resolution while splitting out media types.
+ *
+ * @param name The new name (from XML).
+ *
+ * @see MediaCodecInfo::splitOutType
*/
void setName(const char* name);
/**
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0067344..b28513e 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -359,10 +359,12 @@
snprintf(buffer, SIZE - 1, " owner: \"%s\"\n", info->getOwnerName());
result.append(buffer);
+ snprintf(buffer, SIZE - 1, " hal name: \"%s\"\n", info->getHalName());
+ result.append(buffer);
snprintf(buffer, SIZE - 1, " rank: %u\n", info->getRank());
result.append(buffer);
} else {
- result.append(" aliases, attributes, owner, rank: see above\n");
+ result.append(" aliases, attributes, owner, hal name, rank: see above\n");
}
{
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e06efac..bacf758 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -7084,8 +7084,10 @@
}
AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName();
- AString componentName;
- CHECK(msg->findString("componentName", &componentName));
+ AString componentName = info->getCodecName();
+ // we are no longer using "componentName" as we always pass the codec info for owner.
+ // CHECK(msg->findString("componentName", &componentName));
+ AString halName = info->getHalName();
sp<CodecObserver> observer = new CodecObserver(notify);
sp<IOMX> omx;
@@ -7102,11 +7104,12 @@
pid_t tid = gettid();
int prevPriority = androidGetThreadPriority(tid);
androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
- err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
+ err = omx->allocateNode(halName.c_str(), observer, &omxNode);
androidSetThreadPriority(tid, prevPriority);
if (err != OK) {
- ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
+ ALOGE("Unable to instantiate codec '%s' for '%s' with err %#x.",
+ halName.c_str(), componentName.c_str(), err);
mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
return false;
diff --git a/media/libstagefright/MediaCodecListWriter.cpp b/media/libstagefright/MediaCodecListWriter.cpp
index c4fb199..2048f3b 100644
--- a/media/libstagefright/MediaCodecListWriter.cpp
+++ b/media/libstagefright/MediaCodecListWriter.cpp
@@ -19,9 +19,12 @@
#include <utils/Log.h>
#include <media/stagefright/foundation/AMessage.h>
+#include "media/stagefright/foundation/AString.h"
#include <media/stagefright/MediaCodecListWriter.h>
#include <media/MediaCodecInfo.h>
+#include <string>
+
namespace android {
void MediaCodecListWriter::addGlobalSetting(
@@ -56,8 +59,52 @@
void MediaCodecListWriter::writeCodecInfos(
std::vector<sp<MediaCodecInfo>> *codecInfos) const {
+ // Since the introduction of the NDK MediaCodecList API, each
+ // MediaCodecInfo object can only support a single media type, so infos that
+ // support multiple media types are split into multiple infos.
+ // This process may result in name collisions that are handled here.
+
+ // Prefer codec names that already support a single media type
+ // and also any existing aliases. If an alias matches an existing
+ // codec name, it is ignored, which is the right behavior.
+ std::set<std::string> reservedNames;
for (const sp<MediaCodecInfo> &info : mCodecInfos) {
- codecInfos->push_back(info);
+ Vector<AString> mediaTypes;
+ info->getSupportedMediaTypes(&mediaTypes);
+ if (mediaTypes.size() == 1) {
+ reservedNames.insert(info->getCodecName());
+ }
+ Vector<AString> aliases;
+ info->getAliases(&aliases);
+ for (const AString &alias : aliases) {
+ reservedNames.insert(alias.c_str());
+ }
+ }
+
+ for (const sp<MediaCodecInfo> &info : mCodecInfos) {
+ Vector<AString> mediaTypes;
+ info->getSupportedMediaTypes(&mediaTypes);
+ if (mediaTypes.size() == 1) {
+ codecInfos->push_back(info);
+ } else {
+ // disambiguate each type
+ for (const AString &mediaType : mediaTypes) {
+ // get the type name after the first slash (if exists)
+ ssize_t slashPosition = mediaType.find("/");
+ const char *typeName = mediaType.c_str() + (slashPosition + 1);
+
+ // find a unique name for the split codec info starting with "<name>.<type>"
+ AString newName = AStringPrintf("%s.%s", info->getCodecName(), typeName);
+ std::string newNameStr = newName.c_str();
+ // append increasing suffix of the form ".<number>" until a unique name is found
+ for (size_t ix = 1; reservedNames.count(newNameStr) > 0; ++ix) {
+ newNameStr = AStringPrintf("%s.%zu", newName.c_str(), ix).c_str();
+ }
+
+ codecInfos->push_back(info->splitOutType(mediaType.c_str(), newNameStr.c_str()));
+ reservedNames.insert(newNameStr);
+ }
+ }
}
}
diff --git a/media/module/foundation/include/media/stagefright/foundation/AString.h b/media/module/foundation/include/media/stagefright/foundation/AString.h
index 517774b..7ab6b7c 100644
--- a/media/module/foundation/include/media/stagefright/foundation/AString.h
+++ b/media/module/foundation/include/media/stagefright/foundation/AString.h
@@ -67,6 +67,9 @@
void insert(const AString &from, size_t insertionPos);
void insert(const char *from, size_t size, size_t insertionPos);
+ // Returns the index of the first occurrence of substring in the string, or -1 if not found.
+ // If start is specified, the search is limited to the substring starting at that position.
+ // The start parameter MUST NOT be greater than the string size.
ssize_t find(const char *substring, size_t start = 0) const;
size_t hash() const;