Implement IOmxStore
Separate out MediaCodecsXmlParser and implement IOmxStore and IOMXStore.
Test: make cts -j123 && cts-tradefed run cts-dev -m \
CtsMediaTestCases --compatibility:module-arg \
CtsMediaTestCases:include-annotation:\
android.platform.test.annotations.RequiresDevice
Test: make cts -j123 && cts-tradefed run cts -m \
CtsMediaTestCases -t android.media.cts.MediaCodecListTest
Bug: 37657124
Change-Id: I8c5a3a8fe6defab4f17c8a49bce57452879193dc
diff --git a/media/libmedia/IMediaCodecService.cpp b/media/libmedia/IMediaCodecService.cpp
index 2d62419..adfa93d 100644
--- a/media/libmedia/IMediaCodecService.cpp
+++ b/media/libmedia/IMediaCodecService.cpp
@@ -27,7 +27,8 @@
namespace android {
enum {
- GET_OMX = IBinder::FIRST_CALL_TRANSACTION
+ GET_OMX = IBinder::FIRST_CALL_TRANSACTION,
+ GET_OMX_STORE
};
class BpMediaCodecService : public BpInterface<IMediaCodecService>
@@ -45,6 +46,13 @@
return interface_cast<IOMX>(reply.readStrongBinder());
}
+ virtual sp<IOMXStore> getOMXStore() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaCodecService::getInterfaceDescriptor());
+ remote()->transact(GET_OMX_STORE, data, &reply);
+ return interface_cast<IOMXStore>(reply.readStrongBinder());
+ }
+
};
IMPLEMENT_META_INTERFACE(MediaCodecService, "android.media.IMediaCodecService");
@@ -62,6 +70,12 @@
reply->writeStrongBinder(IInterface::asBinder(omx));
return NO_ERROR;
}
+ case GET_OMX_STORE: {
+ CHECK_INTERFACE(IMediaCodecService, data, reply);
+ sp<IOMXStore> omxStore = getOMXStore();
+ reply->writeStrongBinder(IInterface::asBinder(omxStore));
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 2a74512..a570ffe 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -101,42 +101,46 @@
return OK;
}
-void MediaCodecInfo::CapabilitiesBuilder::addProfileLevel(uint32_t profile, uint32_t level) {
+void MediaCodecInfo::CapabilitiesWriter::addDetail(
+ const char* key, const char* value) {
+ mCap->mDetails->setString(key, value);
+}
+
+void MediaCodecInfo::CapabilitiesWriter::addDetail(
+ const char* key, int32_t value) {
+ mCap->mDetails->setInt32(key, value);
+}
+
+void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
+ uint32_t profile, uint32_t level) {
ProfileLevel profileLevel;
profileLevel.mProfile = profile;
profileLevel.mLevel = level;
- if (mProfileLevelsSorted.indexOf(profileLevel) < 0) {
- mProfileLevels.push_back(profileLevel);
- mProfileLevelsSorted.add(profileLevel);
+ if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
+ mCap->mProfileLevels.push_back(profileLevel);
+ mCap->mProfileLevelsSorted.add(profileLevel);
}
}
-void MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
- if (mColorFormatsSorted.indexOf(format) < 0) {
- mColorFormats.push(format);
- mColorFormatsSorted.add(format);
+void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
+ if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
+ mCap->mColorFormats.push(format);
+ mCap->mColorFormatsSorted.add(format);
}
}
-void MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
- mFlags |= flags;
+void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
+ mCap->mFlags |= flags;
+}
+
+MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
+ MediaCodecInfo::Capabilities* cap) : mCap(cap) {
}
bool MediaCodecInfo::isEncoder() const {
return mIsEncoder;
}
-bool MediaCodecInfo::hasQuirk(const char *name) const {
- if (name) {
- for (size_t ix = 0; ix < mQuirks.size(); ix++) {
- if (mQuirks.itemAt(ix).equalsIgnoreCase(name)) {
- return true;
- }
- }
- }
- return false;
-}
-
void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
mimes->clear();
for (size_t ix = 0; ix < mCaps.size(); ix++) {
@@ -157,20 +161,21 @@
return mName.c_str();
}
+const char *MediaCodecInfo::getOwnerName() const {
+ return mOwner.c_str();
+}
+
// static
sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
AString name = AString::FromParcel(parcel);
+ AString owner = AString::FromParcel(parcel);
bool isEncoder = static_cast<bool>(parcel.readInt32());
- sp<MediaCodecInfo> info = new MediaCodecInfo(name, isEncoder, NULL);
+ sp<MediaCodecInfo> info = new MediaCodecInfo;
+ info->mName = name;
+ info->mOwner = owner;
+ info->mIsEncoder = isEncoder;
size_t size = static_cast<size_t>(parcel.readInt32());
for (size_t i = 0; i < size; i++) {
- AString quirk = AString::FromParcel(parcel);
- if (info != NULL) {
- info->mQuirks.push_back(quirk);
- }
- }
- size = static_cast<size_t>(parcel.readInt32());
- for (size_t i = 0; i < size; i++) {
AString mime = AString::FromParcel(parcel);
sp<Capabilities> caps = Capabilities::FromParcel(parcel);
if (caps == NULL)
@@ -184,11 +189,8 @@
status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
mName.writeToParcel(parcel);
+ mOwner.writeToParcel(parcel);
parcel->writeInt32(mIsEncoder);
- parcel->writeInt32(mQuirks.size());
- for (size_t i = 0; i < mQuirks.size(); i++) {
- mQuirks.itemAt(i).writeToParcel(parcel);
- }
parcel->writeInt32(mCaps.size());
for (size_t i = 0; i < mCaps.size(); i++) {
mCaps.keyAt(i).writeToParcel(parcel);
@@ -208,86 +210,46 @@
return -1;
}
-MediaCodecInfo::MediaCodecInfo(AString name, bool encoder, const char *mime)
- : mName(name),
- mIsEncoder(encoder),
- mHasSoleMime(false) {
- if (mime != NULL) {
- addMime(mime);
- mHasSoleMime = true;
- }
+MediaCodecInfo::MediaCodecInfo() {
}
-status_t MediaCodecInfo::addMime(const char *mime) {
- if (mHasSoleMime) {
- ALOGE("Codec '%s' already had its type specified", mName.c_str());
- return -EINVAL;
- }
- ssize_t ix = getCapabilityIndex(mime);
+void MediaCodecInfoWriter::setName(const char* name) {
+ mInfo->mName = name;
+}
+
+void MediaCodecInfoWriter::setOwner(const char* owner) {
+ mInfo->mOwner = owner;
+}
+
+void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
+ mInfo->mIsEncoder = isEncoder;
+}
+
+std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
+ MediaCodecInfoWriter::addMime(const char *mime) {
+ ssize_t ix = mInfo->getCapabilityIndex(mime);
if (ix >= 0) {
- mCurrentCaps = mCaps.valueAt(ix);
- } else {
- mCurrentCaps = new Capabilities();
- mCaps.add(AString(mime), mCurrentCaps);
+ return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
+ new MediaCodecInfo::CapabilitiesWriter(
+ mInfo->mCaps.valueAt(ix).get()));
}
- return OK;
+ sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
+ mInfo->mCaps.add(AString(mime), caps);
+ return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
+ new MediaCodecInfo::CapabilitiesWriter(caps.get()));
}
-status_t MediaCodecInfo::updateMime(const char *mime) {
- ssize_t ix = getCapabilityIndex(mime);
- if (ix < 0) {
- ALOGE("updateMime mime not found %s", mime);
- return -EINVAL;
- }
-
- mCurrentCaps = mCaps.valueAt(ix);
- return OK;
-}
-
-void MediaCodecInfo::removeMime(const char *mime) {
- ssize_t ix = getCapabilityIndex(mime);
+bool MediaCodecInfoWriter::removeMime(const char *mime) {
+ ssize_t ix = mInfo->getCapabilityIndex(mime);
if (ix >= 0) {
- mCaps.removeItemsAt(ix);
- // mCurrentCaps will be removed when completed
+ mInfo->mCaps.removeItemsAt(ix);
+ return true;
}
+ return false;
}
-status_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
- // TRICKY: copy data to mCurrentCaps as it is a reference to
- // an element of the capabilites map.
- mCurrentCaps->mColorFormats.clear();
- mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
- mCurrentCaps->mProfileLevels.clear();
- mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
- mCurrentCaps->mFlags = caps->mFlags;
- mCurrentCaps->mDetails = caps->mDetails;
- return OK;
-}
-
-void MediaCodecInfo::addQuirk(const char *name) {
- if (!hasQuirk(name)) {
- mQuirks.push(name);
- }
-}
-
-void MediaCodecInfo::complete() {
- mCurrentCaps = NULL;
-}
-
-void MediaCodecInfo::addDetail(const AString &key, const AString &value) {
- mCurrentCaps->mDetails->setString(key.c_str(), value.c_str());
-}
-
-void MediaCodecInfo::addFeature(const AString &key, int32_t value) {
- AString tag = "feature-";
- tag.append(key);
- mCurrentCaps->mDetails->setInt32(tag.c_str(), value);
-}
-
-void MediaCodecInfo::addFeature(const AString &key, const char *value) {
- AString tag = "feature-";
- tag.append(key);
- mCurrentCaps->mDetails->setString(tag.c_str(), value);
+MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
+ mInfo(info) {
}
} // namespace android
diff --git a/media/libmedia/include/media/IMediaCodecService.h b/media/libmedia/include/media/IMediaCodecService.h
index da3c5a03..59fb1c0 100644
--- a/media/libmedia/include/media/IMediaCodecService.h
+++ b/media/libmedia/include/media/IMediaCodecService.h
@@ -22,6 +22,7 @@
#include <binder/Parcel.h>
#include <media/IDataSource.h>
#include <media/IOMX.h>
+#include <media/IOMXStore.h>
namespace android {
@@ -31,6 +32,7 @@
DECLARE_META_INTERFACE(MediaCodecService);
virtual sp<IOMX> getOMX() = 0;
+ virtual sp<IOMXStore> getOMXStore() = 0;
};
class BnMediaCodecService: public BnInterface<IMediaCodecService>
diff --git a/media/libmedia/include/media/IOMXStore.h b/media/libmedia/include/media/IOMXStore.h
index f739c3b..628db70 100644
--- a/media/libmedia/include/media/IOMXStore.h
+++ b/media/libmedia/include/media/IOMXStore.h
@@ -27,11 +27,6 @@
#include <vector>
#include <string>
-/*
-#include <OMX_Core.h>
-#include <OMX_Video.h>
-*/
-
namespace android {
using hardware::media::omx::V1_0::IOmxStore;
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index ef641d2..ab2cd24 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -18,6 +18,7 @@
#define MEDIA_CODEC_INFO_H_
+#include <android-base/macros.h>
#include <binder/Parcel.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
@@ -36,6 +37,9 @@
typedef KeyedVector<AString, AString> CodecSettings;
+struct MediaCodecInfoWriter;
+struct MediaCodecListWriter;
+
struct MediaCodecInfo : public RefBase {
struct ProfileLevel {
uint32_t mProfile;
@@ -45,6 +49,8 @@
}
};
+ struct CapabilitiesWriter;
+
struct Capabilities : public RefBase {
enum {
// decoder flags
@@ -77,72 +83,191 @@
static sp<Capabilities> FromParcel(const Parcel &parcel);
status_t writeToParcel(Parcel *parcel) const;
- DISALLOW_EVIL_CONSTRUCTORS(Capabilities);
+ DISALLOW_COPY_AND_ASSIGN(Capabilities);
friend struct MediaCodecInfo;
+ friend struct MediaCodecInfoWriter;
+ friend struct CapabilitiesWriter;
};
- // Use a subclass to allow setting fields on construction without allowing
- // to do the same throughout the framework.
- struct CapabilitiesBuilder : public Capabilities {
+ /**
+ * This class is used for modifying information inside a `Capabilities`
+ * object. An object of type `CapabilitiesWriter` can be obtained by calling
+ * `MediaCodecInfoWriter::addMime()` or
+ * `MediaCodecInfoWriter::updateMime()`.
+ */
+ struct CapabilitiesWriter {
+ /**
+ * Add a key-value pair to the list of details. If the key already
+ * exists, the old value will be replaced.
+ *
+ * A pair added by this function will be accessible by
+ * `Capabilities::getDetails()`. Call `AMessage::getString()` with the
+ * same key to retrieve the value.
+ *
+ * @param key The key.
+ * @param value The string value.
+ */
+ void addDetail(const char* key, const char* value);
+ /**
+ * Add a key-value pair to the list of details. If the key already
+ * exists, the old value will be replaced.
+ *
+ * A pair added by this function will be accessible by
+ * `Capabilities::getDetails()`. Call `AMessage::getInt32()` with the
+ * same key to retrieve the value.
+ *
+ * @param key The key.
+ * @param value The `int32_t` value.
+ */
+ void addDetail(const char* key, int32_t value);
+ /**
+ * Add a profile-level pair. If this profile-level pair already exists,
+ * it will be ignored.
+ *
+ * @param profile The "profile" component.
+ * @param level The "level" component.
+ */
void addProfileLevel(uint32_t profile, uint32_t level);
+ /**
+ * Add a color format. If this color format already exists, it will be
+ * ignored.
+ *
+ * @param format The color format.
+ */
void addColorFormat(uint32_t format);
+ /**
+ * Add flags. The underlying operation is bitwise-or. In other words,
+ * bits that have already been set will be ignored.
+ *
+ * @param flags The additional flags.
+ */
void addFlags(uint32_t flags);
+ private:
+ /**
+ * The associated `Capabilities` object.
+ */
+ Capabilities* mCap;
+ /**
+ * Construct a writer for the given `Capabilities` object.
+ *
+ * @param cap The `Capabilities` object to be written to.
+ */
+ CapabilitiesWriter(Capabilities* cap);
+
+ friend MediaCodecInfoWriter;
};
bool isEncoder() const;
- bool hasQuirk(const char *name) const;
void getSupportedMimes(Vector<AString> *mimes) const;
const sp<Capabilities> getCapabilitiesFor(const char *mime) const;
const char *getCodecName() const;
/**
+ * Return the name of the service that hosts the codec. This value is not
+ * visible at the Java level.
+ *
+ * Currently, this is the "instance name" of the IOmx service.
+ */
+ const char *getOwnerName() const;
+
+ /**
* Serialization over Binder
*/
static sp<MediaCodecInfo> FromParcel(const Parcel &parcel);
status_t writeToParcel(Parcel *parcel) const;
private:
- // variable set only in constructor - these are accessed by MediaCodecList
- // to avoid duplication of same variables
AString mName;
+ AString mOwner;
bool mIsEncoder;
- bool mHasSoleMime; // was initialized with mime
-
- Vector<AString> mQuirks;
KeyedVector<AString, sp<Capabilities> > mCaps;
- sp<Capabilities> mCurrentCaps; // currently initalized capabilities
-
ssize_t getCapabilityIndex(const char *mime) const;
- /* Methods used by MediaCodecList to construct the info
- * object from XML.
- *
- * After info object is created:
- * - additional quirks can be added
- * - additional mimes can be added
- * - OMX codec capabilities can be set for the current mime-type
- * - a capability detail can be set for the current mime-type
- * - a feature can be set for the current mime-type
- * - info object can be completed when parsing of a mime-type is done
+ /**
+ * Construct an `MediaCodecInfo` object. After the construction, its
+ * information can be set via an `MediaCodecInfoWriter` object obtained from
+ * `MediaCodecListWriter::addMediaCodecInfo()`.
*/
- MediaCodecInfo(AString name, bool encoder, const char *mime);
- void addQuirk(const char *name);
- status_t addMime(const char *mime);
- status_t updateMime(const char *mime);
+ MediaCodecInfo();
- status_t initializeCapabilities(const sp<Capabilities> &caps);
- void addDetail(const AString &key, const AString &value);
- void addFeature(const AString &key, int32_t value);
- void addFeature(const AString &key, const char *value);
- void removeMime(const char *mime);
- void complete();
+ DISALLOW_COPY_AND_ASSIGN(MediaCodecInfo);
- DISALLOW_EVIL_CONSTRUCTORS(MediaCodecInfo);
-
- friend struct MediaCodecList;
friend class MediaCodecListOverridesTest;
+ friend struct MediaCodecInfoWriter;
+ friend struct MediaCodecListWriter;
+};
+
+/**
+ * This class is to be used by a `MediaCodecListBuilderBase` instance to
+ * populate information inside the associated `MediaCodecInfo` object.
+ *
+ * The only place where an instance of `MediaCodecInfoWriter` can be constructed
+ * is `MediaCodecListWriter::addMediaCodecInfo()`. A `MediaCodecListBuilderBase`
+ * instance should call `MediaCodecListWriter::addMediaCodecInfo()` on the given
+ * `MediaCodecListWriter` object given as an input to
+ * `MediaCodecListBuilderBase::buildMediaCodecList()`.
+ */
+struct MediaCodecInfoWriter {
+ /**
+ * Set the name of the codec.
+ *
+ * @param name The new name.
+ */
+ void setName(const char* name);
+ /**
+ * Set the owner name of the codec.
+ *
+ * This "owner name" is the name of the `IOmx` instance that supports this
+ * codec.
+ *
+ * @param owner The new owner name.
+ */
+ void setOwner(const char* owner);
+ /**
+ * Set whether this codec is an encoder or a decoder.
+ *
+ * @param isEncoder Whether this codec is an encoder or a decoder.
+ */
+ void setEncoder(bool isEncoder = true);
+ /**
+ * Add a mime to an indexed list and return a `CapabilitiesWriter` object
+ * that can be used for modifying the associated `Capabilities`.
+ *
+ * If the mime already exists, this function will return the
+ * `CapabilitiesWriter` associated with the mime.
+ *
+ * @param[in] mime The name of a new mime to add.
+ * @return writer The `CapabilitiesWriter` object for modifying the
+ * `Capabilities` associated with the mime. `writer` will be valid
+ * regardless of whether `mime` already exists or not.
+ */
+ std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMime(
+ const char* mime);
+ /**
+ * Remove a mime.
+ *
+ * @param mime The name of the mime to remove.
+ * @return `true` if `mime` is removed; `false` if `mime` is not found.
+ */
+ bool removeMime(const char* mime);
+private:
+ /**
+ * The associated `MediaCodecInfo`.
+ */
+ MediaCodecInfo* mInfo;
+ /**
+ * Construct the `MediaCodecInfoWriter` object associated with the given
+ * `MediaCodecInfo` object.
+ *
+ * @param info The underlying `MediaCodecInfo` object.
+ */
+ MediaCodecInfoWriter(MediaCodecInfo* info);
+
+ DISALLOW_COPY_AND_ASSIGN(MediaCodecInfoWriter);
+
+ friend struct MediaCodecListWriter;
};
} // namespace android