xref: /aosp_15_r20/frameworks/av/media/libmedia/MediaCodecInfo.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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/MediaCodecInfo.h>
22 
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/foundation/AMessage.h>
25 #include <binder/Parcel.h>
26 
27 namespace android {
28 
29 // initialize max supported instances with default value.
30 int32_t MediaCodecInfo::sMaxSupportedInstances = 0;
31 
32 /** This redundant redeclaration is needed for C++ pre 14 */
33 constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
34 constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
35 constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
36 constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
37 constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
38 constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
39 constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
40 constexpr char MediaCodecInfo::Capabilities::FEATURE_DETACHED_SURFACE[];
41 
getSupportedProfileLevels(Vector<ProfileLevel> * profileLevels) const42 void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
43         Vector<ProfileLevel> *profileLevels) const {
44     profileLevels->clear();
45     profileLevels->appendVector(mProfileLevels);
46 }
47 
getSupportedColorFormats(Vector<uint32_t> * colorFormats) const48 void MediaCodecInfo::Capabilities::getSupportedColorFormats(
49         Vector<uint32_t> *colorFormats) const {
50     colorFormats->clear();
51     colorFormats->appendVector(mColorFormats);
52 }
53 
getDetails() const54 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
55     return mDetails;
56 }
57 
Capabilities()58 MediaCodecInfo::Capabilities::Capabilities() {
59     mDetails = new AMessage;
60 }
61 
62 // static
FromParcel(const Parcel & parcel)63 sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
64         const Parcel &parcel) {
65     sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
66     size_t size = static_cast<size_t>(parcel.readInt32());
67     for (size_t i = 0; i < size; i++) {
68         ProfileLevel profileLevel;
69         profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
70         profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
71         if (caps != NULL) {
72             caps->mProfileLevels.push_back(profileLevel);
73         }
74     }
75     size = static_cast<size_t>(parcel.readInt32());
76     for (size_t i = 0; i < size; i++) {
77         uint32_t color = static_cast<uint32_t>(parcel.readInt32());
78         if (caps != NULL) {
79             caps->mColorFormats.push_back(color);
80         }
81     }
82     sp<AMessage> details = AMessage::FromParcel(parcel);
83     if (details == NULL)
84         return NULL;
85     if (caps != NULL) {
86         caps->mDetails = details;
87     }
88     return caps;
89 }
90 
writeToParcel(Parcel * parcel) const91 status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
92     CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX));
93     parcel->writeInt32(mProfileLevels.size());
94     for (size_t i = 0; i < mProfileLevels.size(); i++) {
95         parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
96         parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
97     }
98     CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX));
99     parcel->writeInt32(mColorFormats.size());
100     for (size_t i = 0; i < mColorFormats.size(); i++) {
101         parcel->writeInt32(mColorFormats.itemAt(i));
102     }
103     mDetails->writeToParcel(parcel);
104     return OK;
105 }
106 
addDetail(const char * key,const char * value)107 void MediaCodecInfo::CapabilitiesWriter::addDetail(
108         const char* key, const char* value) {
109     mCap->mDetails->setString(key, value);
110 }
111 
addDetail(const char * key,int32_t value)112 void MediaCodecInfo::CapabilitiesWriter::addDetail(
113         const char* key, int32_t value) {
114     mCap->mDetails->setInt32(key, value);
115 }
116 
removeDetail(const char * key)117 void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
118     if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
119         ALOGD("successfully removed detail %s", key);
120     } else {
121         ALOGD("detail %s wasn't present to remove", key);
122     }
123 }
124 
addProfileLevel(uint32_t profile,uint32_t level)125 void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
126         uint32_t profile, uint32_t level) {
127     ProfileLevel profileLevel;
128     profileLevel.mProfile = profile;
129     profileLevel.mLevel = level;
130     if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
131         mCap->mProfileLevels.push_back(profileLevel);
132         mCap->mProfileLevelsSorted.add(profileLevel);
133     }
134 }
135 
addColorFormat(uint32_t format)136 void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
137     if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
138         mCap->mColorFormats.push(format);
139         mCap->mColorFormatsSorted.add(format);
140     }
141 }
142 
CapabilitiesWriter(MediaCodecInfo::Capabilities * cap)143 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
144         MediaCodecInfo::Capabilities* cap) : mCap(cap) {
145 }
146 
getAttributes() const147 MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
148     return mAttributes;
149 }
150 
getRank() const151 uint32_t MediaCodecInfo::getRank() const {
152     return mRank;
153 }
154 
getAliases(Vector<AString> * aliases) const155 void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
156     *aliases = mAliases;
157 }
158 
getSupportedMediaTypes(Vector<AString> * mediaTypes) const159 void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
160     mediaTypes->clear();
161     for (size_t ix = 0; ix < mCaps.size(); ix++) {
162         mediaTypes->push_back(mCaps.keyAt(ix));
163     }
164 }
165 
166 const sp<MediaCodecInfo::Capabilities>
getCapabilitiesFor(const char * mediaType) const167 MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
168     ssize_t ix = getCapabilityIndex(mediaType);
169     if (ix >= 0) {
170         return mCaps.valueAt(ix);
171     }
172     return NULL;
173 }
174 
getCodecCapsFor(const char * mediaType) const175 const std::shared_ptr<CodecCapabilities> MediaCodecInfo::getCodecCapsFor(
176         const char *mediaType) const {
177     ssize_t ix = getCodecCapIndex(mediaType);
178     if (ix >= 0) {
179         return mCodecCaps.valueAt(ix);
180     }
181     return nullptr;
182 }
183 
getCodecName() const184 const char *MediaCodecInfo::getCodecName() const {
185     return mName.c_str();
186 }
187 
getOwnerName() const188 const char *MediaCodecInfo::getOwnerName() const {
189     return mOwner.c_str();
190 }
191 
192 // static
FromParcel(const Parcel & parcel)193 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
194     sMaxSupportedInstances = parcel.readInt32();
195     AString name = AString::FromParcel(parcel);
196     AString owner = AString::FromParcel(parcel);
197     Attributes attributes = static_cast<Attributes>(parcel.readInt32());
198     uint32_t rank = parcel.readUint32();
199     sp<MediaCodecInfo> info = new MediaCodecInfo;
200     info->mName = name;
201     info->mOwner = owner;
202     info->mAttributes = attributes;
203     info->mRank = rank;
204     size_t numAliases = static_cast<size_t>(parcel.readInt32());
205     for (size_t i = 0; i < numAliases; i++) {
206         AString alias = AString::FromParcel(parcel);
207         info->mAliases.add(alias);
208     }
209     size_t size = static_cast<size_t>(parcel.readInt32());
210     for (size_t i = 0; i < size; i++) {
211         AString mediaType = AString::FromParcel(parcel);
212         sp<Capabilities> caps = Capabilities::FromParcel(parcel);
213         if (caps == NULL)
214             return NULL;
215         if (info != NULL) {
216             info->mCaps.add(mediaType, caps);
217             std::shared_ptr<CodecCapabilities> codecCaps
218                     = MediaCodecInfoWriter::BuildCodecCapabilities(
219                             mediaType.c_str(), caps, info->isEncoder());
220             info->mCodecCaps.add(mediaType, codecCaps);
221         }
222     }
223     return info;
224 }
225 
writeToParcel(Parcel * parcel) const226 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
227     parcel->writeInt32(sMaxSupportedInstances);
228     mName.writeToParcel(parcel);
229     mOwner.writeToParcel(parcel);
230     parcel->writeInt32(mAttributes);
231     parcel->writeUint32(mRank);
232     parcel->writeInt32(mAliases.size());
233     for (const AString &alias : mAliases) {
234         alias.writeToParcel(parcel);
235     }
236     parcel->writeInt32(mCaps.size());
237     for (size_t i = 0; i < mCaps.size(); i++) {
238         mCaps.keyAt(i).writeToParcel(parcel);
239         mCaps.valueAt(i)->writeToParcel(parcel);
240     }
241     return OK;
242 }
243 
getCapabilityIndex(const char * mediaType) const244 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
245     if (mediaType) {
246         for (size_t ix = 0; ix < mCaps.size(); ix++) {
247             if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
248                 return ix;
249             }
250         }
251     }
252     return -1;
253 }
254 
getCodecCapIndex(const char * mediaType) const255 ssize_t MediaCodecInfo::getCodecCapIndex(const char *mediaType) const {
256     if (mediaType == nullptr) {
257         return -1;
258     }
259 
260     if (mCodecCaps.size() != mCaps.size()) {
261         ALOGE("Size of mCodecCaps and mCaps do not match, which are %zu and %zu",
262                 mCodecCaps.size(), mCaps.size());
263     }
264 
265     for (size_t ix = 0; ix < mCodecCaps.size(); ix++) {
266         if (mCodecCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
267             return ix;
268         }
269     }
270 
271     return -1;
272 }
273 
MediaCodecInfo()274 MediaCodecInfo::MediaCodecInfo()
275     : mAttributes((MediaCodecInfo::Attributes)0),
276       mRank(0x100) {
277 }
278 
setName(const char * name)279 void MediaCodecInfoWriter::setName(const char* name) {
280     mInfo->mName = name;
281 }
282 
addAlias(const char * name)283 void MediaCodecInfoWriter::addAlias(const char* name) {
284     mInfo->mAliases.add(name);
285 }
286 
setOwner(const char * owner)287 void MediaCodecInfoWriter::setOwner(const char* owner) {
288     mInfo->mOwner = owner;
289 }
290 
setAttributes(typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes)291 void MediaCodecInfoWriter::setAttributes(
292         typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
293     mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
294 }
295 
setRank(uint32_t rank)296 void MediaCodecInfoWriter::setRank(uint32_t rank) {
297     mInfo->mRank = rank;
298 }
299 
300 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
addMediaType(const char * mediaType)301         MediaCodecInfoWriter::addMediaType(const char *mediaType) {
302     ssize_t ix = mInfo->getCapabilityIndex(mediaType);
303     if (ix >= 0) {
304         return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
305                 new MediaCodecInfo::CapabilitiesWriter(
306                 mInfo->mCaps.valueAt(ix).get()));
307     }
308     sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
309     mInfo->mCaps.add(AString(mediaType), caps);
310     return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
311             new MediaCodecInfo::CapabilitiesWriter(caps.get()));
312 }
313 
removeMediaType(const char * mediaType)314 bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
315     ssize_t ix = mInfo->getCapabilityIndex(mediaType);
316     if (ix >= 0) {
317         mInfo->mCaps.removeItemsAt(ix);
318         return true;
319     }
320     return false;
321 }
322 
createCodecCaps()323 void MediaCodecInfoWriter::createCodecCaps() {
324     mInfo->mCodecCaps.clear();
325     for (size_t ix = 0; ix < mInfo->mCaps.size(); ix++) {
326         AString mediaType = mInfo->mCaps.keyAt(ix);
327         sp<MediaCodecInfo::Capabilities> caps = mInfo->mCaps.valueAt(ix);
328         mInfo->mCodecCaps.add(mediaType,
329                 BuildCodecCapabilities(mediaType.c_str(), caps, mInfo->isEncoder(),
330                 MediaCodecInfo::sMaxSupportedInstances));
331     }
332 }
333 
334 // static
BuildCodecCapabilities(const char * mediaType,sp<MediaCodecInfo::Capabilities> caps,bool isEncoder,int32_t maxSupportedInstances)335 std::shared_ptr<CodecCapabilities> MediaCodecInfoWriter::BuildCodecCapabilities(
336         const char *mediaType, sp<MediaCodecInfo::Capabilities> caps, bool isEncoder,
337         int32_t maxSupportedInstances) {
338     Vector<ProfileLevel> profileLevels_;
339     Vector<uint32_t> colorFormats_;
340     caps->getSupportedProfileLevels(&profileLevels_);
341     caps->getSupportedColorFormats(&colorFormats_);
342 
343     std::vector<ProfileLevel> profileLevels;
344     std::vector<uint32_t> colorFormats;
345     for (ProfileLevel pl : profileLevels_) {
346         profileLevels.push_back(pl);
347     }
348     for (uint32_t cf : colorFormats_) {
349         colorFormats.push_back(cf);
350     }
351 
352     sp<AMessage> defaultFormat = new AMessage();
353     defaultFormat->setString("mime", mediaType);
354 
355     sp<AMessage> capabilitiesInfo = caps->getDetails();
356 
357     std::shared_ptr<CodecCapabilities> codecCaps = std::make_shared<CodecCapabilities>();
358     codecCaps->init(profileLevels, colorFormats, isEncoder, defaultFormat,
359             capabilitiesInfo, maxSupportedInstances);
360 
361     return codecCaps;
362 }
363 
364 // static
SetMaxSupportedInstances(int32_t maxSupportedInstances)365 void MediaCodecInfoWriter::SetMaxSupportedInstances(int32_t maxSupportedInstances) {
366     MediaCodecInfo::sMaxSupportedInstances = maxSupportedInstances;
367 }
368 
MediaCodecInfoWriter(MediaCodecInfo * info)369 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
370     mInfo(info) {
371 }
372 
373 }  // namespace android
374