• 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 
getSupportedProfileLevels(Vector<ProfileLevel> * profileLevels) const31 void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
32         Vector<ProfileLevel> *profileLevels) const {
33     profileLevels->clear();
34     profileLevels->appendVector(mProfileLevels);
35 }
36 
getSupportedColorFormats(Vector<uint32_t> * colorFormats) const37 void MediaCodecInfo::Capabilities::getSupportedColorFormats(
38         Vector<uint32_t> *colorFormats) const {
39     colorFormats->clear();
40     colorFormats->appendVector(mColorFormats);
41 }
42 
getFlags() const43 uint32_t MediaCodecInfo::Capabilities::getFlags() const {
44     return mFlags;
45 }
46 
getDetails() const47 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
48     return mDetails;
49 }
50 
Capabilities()51 MediaCodecInfo::Capabilities::Capabilities()
52   : mFlags(0) {
53     mDetails = new AMessage;
54 }
55 
56 // static
FromParcel(const Parcel & parcel)57 sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
58         const Parcel &parcel) {
59     sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
60     size_t size = static_cast<size_t>(parcel.readInt32());
61     for (size_t i = 0; i < size; i++) {
62         ProfileLevel profileLevel;
63         profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
64         profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
65         if (caps != NULL) {
66             caps->mProfileLevels.push_back(profileLevel);
67         }
68     }
69     size = static_cast<size_t>(parcel.readInt32());
70     for (size_t i = 0; i < size; i++) {
71         uint32_t color = static_cast<uint32_t>(parcel.readInt32());
72         if (caps != NULL) {
73             caps->mColorFormats.push_back(color);
74         }
75     }
76     uint32_t flags = static_cast<uint32_t>(parcel.readInt32());
77     sp<AMessage> details = AMessage::FromParcel(parcel);
78     if (details == NULL)
79         return NULL;
80     if (caps != NULL) {
81         caps->mFlags = flags;
82         caps->mDetails = details;
83     }
84     return caps;
85 }
86 
writeToParcel(Parcel * parcel) const87 status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
88     CHECK_LE(mProfileLevels.size(), INT32_MAX);
89     parcel->writeInt32(mProfileLevels.size());
90     for (size_t i = 0; i < mProfileLevels.size(); i++) {
91         parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
92         parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
93     }
94     CHECK_LE(mColorFormats.size(), INT32_MAX);
95     parcel->writeInt32(mColorFormats.size());
96     for (size_t i = 0; i < mColorFormats.size(); i++) {
97         parcel->writeInt32(mColorFormats.itemAt(i));
98     }
99     parcel->writeInt32(mFlags);
100     mDetails->writeToParcel(parcel);
101     return OK;
102 }
103 
addProfileLevel(uint32_t profile,uint32_t level)104 void MediaCodecInfo::CapabilitiesBuilder::addProfileLevel(uint32_t profile, uint32_t level) {
105     ProfileLevel profileLevel;
106     profileLevel.mProfile = profile;
107     profileLevel.mLevel = level;
108     mProfileLevels.push_back(profileLevel);
109 }
110 
addColorFormat(uint32_t format)111 void MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
112     mColorFormats.push(format);
113 }
114 
addFlags(uint32_t flags)115 void MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
116     mFlags |= flags;
117 }
118 
isEncoder() const119 bool MediaCodecInfo::isEncoder() const {
120     return mIsEncoder;
121 }
122 
hasQuirk(const char * name) const123 bool MediaCodecInfo::hasQuirk(const char *name) const {
124     for (size_t ix = 0; ix < mQuirks.size(); ix++) {
125         if (mQuirks.itemAt(ix).equalsIgnoreCase(name)) {
126             return true;
127         }
128     }
129     return false;
130 }
131 
getSupportedMimes(Vector<AString> * mimes) const132 void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
133     mimes->clear();
134     for (size_t ix = 0; ix < mCaps.size(); ix++) {
135         mimes->push_back(mCaps.keyAt(ix));
136     }
137 }
138 
139 const sp<MediaCodecInfo::Capabilities>
getCapabilitiesFor(const char * mime) const140 MediaCodecInfo::getCapabilitiesFor(const char *mime) const {
141     ssize_t ix = getCapabilityIndex(mime);
142     if (ix >= 0) {
143         return mCaps.valueAt(ix);
144     }
145     return NULL;
146 }
147 
getCodecName() const148 const char *MediaCodecInfo::getCodecName() const {
149     return mName.c_str();
150 }
151 
152 // static
FromParcel(const Parcel & parcel)153 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
154     AString name = AString::FromParcel(parcel);
155     bool isEncoder = static_cast<bool>(parcel.readInt32());
156     sp<MediaCodecInfo> info = new MediaCodecInfo(name, isEncoder, NULL);
157     size_t size = static_cast<size_t>(parcel.readInt32());
158     for (size_t i = 0; i < size; i++) {
159         AString quirk = AString::FromParcel(parcel);
160         if (info != NULL) {
161             info->mQuirks.push_back(quirk);
162         }
163     }
164     size = static_cast<size_t>(parcel.readInt32());
165     for (size_t i = 0; i < size; i++) {
166         AString mime = AString::FromParcel(parcel);
167         sp<Capabilities> caps = Capabilities::FromParcel(parcel);
168         if (caps == NULL)
169             return NULL;
170         if (info != NULL) {
171             info->mCaps.add(mime, caps);
172         }
173     }
174     return info;
175 }
176 
writeToParcel(Parcel * parcel) const177 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
178     mName.writeToParcel(parcel);
179     parcel->writeInt32(mIsEncoder);
180     parcel->writeInt32(mQuirks.size());
181     for (size_t i = 0; i < mQuirks.size(); i++) {
182         mQuirks.itemAt(i).writeToParcel(parcel);
183     }
184     parcel->writeInt32(mCaps.size());
185     for (size_t i = 0; i < mCaps.size(); i++) {
186         mCaps.keyAt(i).writeToParcel(parcel);
187         mCaps.valueAt(i)->writeToParcel(parcel);
188     }
189     return OK;
190 }
191 
getCapabilityIndex(const char * mime) const192 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
193     for (size_t ix = 0; ix < mCaps.size(); ix++) {
194         if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
195             return ix;
196         }
197     }
198     return -1;
199 }
200 
MediaCodecInfo(AString name,bool encoder,const char * mime)201 MediaCodecInfo::MediaCodecInfo(AString name, bool encoder, const char *mime)
202     : mName(name),
203       mIsEncoder(encoder),
204       mHasSoleMime(false) {
205     if (mime != NULL) {
206         addMime(mime);
207         mHasSoleMime = true;
208     }
209 }
210 
addMime(const char * mime)211 status_t MediaCodecInfo::addMime(const char *mime) {
212     if (mHasSoleMime) {
213         ALOGE("Codec '%s' already had its type specified", mName.c_str());
214         return -EINVAL;
215     }
216     ssize_t ix = getCapabilityIndex(mime);
217     if (ix >= 0) {
218         mCurrentCaps = mCaps.valueAt(ix);
219     } else {
220         mCurrentCaps = new Capabilities();
221         mCaps.add(AString(mime), mCurrentCaps);
222     }
223     return OK;
224 }
225 
updateMime(const char * mime)226 status_t MediaCodecInfo::updateMime(const char *mime) {
227     ssize_t ix = getCapabilityIndex(mime);
228     if (ix < 0) {
229         ALOGE("updateMime mime not found %s", mime);
230         return -EINVAL;
231     }
232 
233     mCurrentCaps = mCaps.valueAt(ix);
234     return OK;
235 }
236 
removeMime(const char * mime)237 void MediaCodecInfo::removeMime(const char *mime) {
238     ssize_t ix = getCapabilityIndex(mime);
239     if (ix >= 0) {
240         mCaps.removeItemsAt(ix);
241         // mCurrentCaps will be removed when completed
242     }
243 }
244 
initializeCapabilities(const sp<Capabilities> & caps)245 status_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
246     // TRICKY: copy data to mCurrentCaps as it is a reference to
247     // an element of the capabilites map.
248     mCurrentCaps->mColorFormats.clear();
249     mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
250     mCurrentCaps->mProfileLevels.clear();
251     mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
252     mCurrentCaps->mFlags = caps->mFlags;
253     mCurrentCaps->mDetails = caps->mDetails;
254     return OK;
255 }
256 
addQuirk(const char * name)257 void MediaCodecInfo::addQuirk(const char *name) {
258     if (!hasQuirk(name)) {
259         mQuirks.push(name);
260     }
261 }
262 
complete()263 void MediaCodecInfo::complete() {
264     mCurrentCaps = NULL;
265 }
266 
addDetail(const AString & key,const AString & value)267 void MediaCodecInfo::addDetail(const AString &key, const AString &value) {
268     mCurrentCaps->mDetails->setString(key.c_str(), value.c_str());
269 }
270 
addFeature(const AString & key,int32_t value)271 void MediaCodecInfo::addFeature(const AString &key, int32_t value) {
272     AString tag = "feature-";
273     tag.append(key);
274     mCurrentCaps->mDetails->setInt32(tag.c_str(), value);
275 }
276 
addFeature(const AString & key,const char * value)277 void MediaCodecInfo::addFeature(const AString &key, const char *value) {
278     AString tag = "feature-";
279     tag.append(key);
280     mCurrentCaps->mDetails->setString(tag.c_str(), value);
281 }
282 
283 }  // namespace android
284