1 /*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "MediaCodecInfo"
19 #include <utils/Log.h>
20
21 #include <media/IOMX.h>
22
23 #include <media/MediaCodecInfo.h>
24
25 #include <media/stagefright/foundation/ADebug.h>
26 #include <media/stagefright/foundation/AMessage.h>
27 #include <binder/Parcel.h>
28
29 namespace android {
30
31 /** This redundant redeclaration is needed for C++ pre 14 */
32 constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
33 constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
34 constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
35 constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
36 constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
37 constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
38 constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
39 constexpr char MediaCodecInfo::Capabilities::FEATURE_DETACHED_SURFACE[];
40
getSupportedProfileLevels(Vector<ProfileLevel> * profileLevels) const41 void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
42 Vector<ProfileLevel> *profileLevels) const {
43 profileLevels->clear();
44 profileLevels->appendVector(mProfileLevels);
45 }
46
getSupportedColorFormats(Vector<uint32_t> * colorFormats) const47 void MediaCodecInfo::Capabilities::getSupportedColorFormats(
48 Vector<uint32_t> *colorFormats) const {
49 colorFormats->clear();
50 colorFormats->appendVector(mColorFormats);
51 }
52
getDetails() const53 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
54 return mDetails;
55 }
56
Capabilities()57 MediaCodecInfo::Capabilities::Capabilities() {
58 mDetails = new AMessage;
59 }
60
61 // static
FromParcel(const Parcel & parcel)62 sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
63 const Parcel &parcel) {
64 sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
65 size_t size = static_cast<size_t>(parcel.readInt32());
66 for (size_t i = 0; i < size; i++) {
67 ProfileLevel profileLevel;
68 profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
69 profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
70 if (caps != NULL) {
71 caps->mProfileLevels.push_back(profileLevel);
72 }
73 }
74 size = static_cast<size_t>(parcel.readInt32());
75 for (size_t i = 0; i < size; i++) {
76 uint32_t color = static_cast<uint32_t>(parcel.readInt32());
77 if (caps != NULL) {
78 caps->mColorFormats.push_back(color);
79 }
80 }
81 sp<AMessage> details = AMessage::FromParcel(parcel);
82 if (details == NULL)
83 return NULL;
84 if (caps != NULL) {
85 caps->mDetails = details;
86 }
87 return caps;
88 }
89
writeToParcel(Parcel * parcel) const90 status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
91 CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX));
92 parcel->writeInt32(mProfileLevels.size());
93 for (size_t i = 0; i < mProfileLevels.size(); i++) {
94 parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
95 parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
96 }
97 CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX));
98 parcel->writeInt32(mColorFormats.size());
99 for (size_t i = 0; i < mColorFormats.size(); i++) {
100 parcel->writeInt32(mColorFormats.itemAt(i));
101 }
102 mDetails->writeToParcel(parcel);
103 return OK;
104 }
105
addDetail(const char * key,const char * value)106 void MediaCodecInfo::CapabilitiesWriter::addDetail(
107 const char* key, const char* value) {
108 mCap->mDetails->setString(key, value);
109 }
110
addDetail(const char * key,int32_t value)111 void MediaCodecInfo::CapabilitiesWriter::addDetail(
112 const char* key, int32_t value) {
113 mCap->mDetails->setInt32(key, value);
114 }
115
removeDetail(const char * key)116 void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
117 if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
118 ALOGD("successfully removed detail %s", key);
119 } else {
120 ALOGD("detail %s wasn't present to remove", key);
121 }
122 }
123
addProfileLevel(uint32_t profile,uint32_t level)124 void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
125 uint32_t profile, uint32_t level) {
126 ProfileLevel profileLevel;
127 profileLevel.mProfile = profile;
128 profileLevel.mLevel = level;
129 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
130 mCap->mProfileLevels.push_back(profileLevel);
131 mCap->mProfileLevelsSorted.add(profileLevel);
132 }
133 }
134
addColorFormat(uint32_t format)135 void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
136 if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
137 mCap->mColorFormats.push(format);
138 mCap->mColorFormatsSorted.add(format);
139 }
140 }
141
CapabilitiesWriter(MediaCodecInfo::Capabilities * cap)142 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
143 MediaCodecInfo::Capabilities* cap) : mCap(cap) {
144 }
145
getAttributes() const146 MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
147 return mAttributes;
148 }
149
getRank() const150 uint32_t MediaCodecInfo::getRank() const {
151 return mRank;
152 }
153
getAliases(Vector<AString> * aliases) const154 void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
155 *aliases = mAliases;
156 }
157
getSupportedMediaTypes(Vector<AString> * mediaTypes) const158 void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
159 mediaTypes->clear();
160 for (size_t ix = 0; ix < mCaps.size(); ix++) {
161 mediaTypes->push_back(mCaps.keyAt(ix));
162 }
163 }
164
165 const sp<MediaCodecInfo::Capabilities>
getCapabilitiesFor(const char * mediaType) const166 MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
167 ssize_t ix = getCapabilityIndex(mediaType);
168 if (ix >= 0) {
169 return mCaps.valueAt(ix);
170 }
171 return NULL;
172 }
173
getCodecName() const174 const char *MediaCodecInfo::getCodecName() const {
175 return mName.c_str();
176 }
177
getOwnerName() const178 const char *MediaCodecInfo::getOwnerName() const {
179 return mOwner.c_str();
180 }
181
182 // static
FromParcel(const Parcel & parcel)183 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
184 AString name = AString::FromParcel(parcel);
185 AString owner = AString::FromParcel(parcel);
186 Attributes attributes = static_cast<Attributes>(parcel.readInt32());
187 uint32_t rank = parcel.readUint32();
188 sp<MediaCodecInfo> info = new MediaCodecInfo;
189 info->mName = name;
190 info->mOwner = owner;
191 info->mAttributes = attributes;
192 info->mRank = rank;
193 size_t numAliases = static_cast<size_t>(parcel.readInt32());
194 for (size_t i = 0; i < numAliases; i++) {
195 AString alias = AString::FromParcel(parcel);
196 info->mAliases.add(alias);
197 }
198 size_t size = static_cast<size_t>(parcel.readInt32());
199 for (size_t i = 0; i < size; i++) {
200 AString mediaType = AString::FromParcel(parcel);
201 sp<Capabilities> caps = Capabilities::FromParcel(parcel);
202 if (caps == NULL)
203 return NULL;
204 if (info != NULL) {
205 info->mCaps.add(mediaType, caps);
206 }
207 }
208 return info;
209 }
210
writeToParcel(Parcel * parcel) const211 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
212 mName.writeToParcel(parcel);
213 mOwner.writeToParcel(parcel);
214 parcel->writeInt32(mAttributes);
215 parcel->writeUint32(mRank);
216 parcel->writeInt32(mAliases.size());
217 for (const AString &alias : mAliases) {
218 alias.writeToParcel(parcel);
219 }
220 parcel->writeInt32(mCaps.size());
221 for (size_t i = 0; i < mCaps.size(); i++) {
222 mCaps.keyAt(i).writeToParcel(parcel);
223 mCaps.valueAt(i)->writeToParcel(parcel);
224 }
225 return OK;
226 }
227
getCapabilityIndex(const char * mediaType) const228 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
229 if (mediaType) {
230 for (size_t ix = 0; ix < mCaps.size(); ix++) {
231 if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
232 return ix;
233 }
234 }
235 }
236 return -1;
237 }
238
MediaCodecInfo()239 MediaCodecInfo::MediaCodecInfo()
240 : mAttributes((MediaCodecInfo::Attributes)0),
241 mRank(0x100) {
242 }
243
setName(const char * name)244 void MediaCodecInfoWriter::setName(const char* name) {
245 mInfo->mName = name;
246 }
247
addAlias(const char * name)248 void MediaCodecInfoWriter::addAlias(const char* name) {
249 mInfo->mAliases.add(name);
250 }
251
setOwner(const char * owner)252 void MediaCodecInfoWriter::setOwner(const char* owner) {
253 mInfo->mOwner = owner;
254 }
255
setAttributes(typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes)256 void MediaCodecInfoWriter::setAttributes(
257 typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
258 mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
259 }
260
setRank(uint32_t rank)261 void MediaCodecInfoWriter::setRank(uint32_t rank) {
262 mInfo->mRank = rank;
263 }
264
265 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
addMediaType(const char * mediaType)266 MediaCodecInfoWriter::addMediaType(const char *mediaType) {
267 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
268 if (ix >= 0) {
269 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
270 new MediaCodecInfo::CapabilitiesWriter(
271 mInfo->mCaps.valueAt(ix).get()));
272 }
273 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
274 mInfo->mCaps.add(AString(mediaType), caps);
275 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
276 new MediaCodecInfo::CapabilitiesWriter(caps.get()));
277 }
278
removeMediaType(const char * mediaType)279 bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
280 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
281 if (ix >= 0) {
282 mInfo->mCaps.removeItemsAt(ix);
283 return true;
284 }
285 return false;
286 }
287
MediaCodecInfoWriter(MediaCodecInfo * info)288 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
289 mInfo(info) {
290 }
291
292 } // namespace android
293