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