• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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