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(), static_cast<size_t>(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(), static_cast<size_t>(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
addDetail(const char * key,const char * value)104 void MediaCodecInfo::CapabilitiesWriter::addDetail(
105 const char* key, const char* value) {
106 mCap->mDetails->setString(key, value);
107 }
108
addDetail(const char * key,int32_t value)109 void MediaCodecInfo::CapabilitiesWriter::addDetail(
110 const char* key, int32_t value) {
111 mCap->mDetails->setInt32(key, value);
112 }
113
addProfileLevel(uint32_t profile,uint32_t level)114 void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
115 uint32_t profile, uint32_t level) {
116 ProfileLevel profileLevel;
117 profileLevel.mProfile = profile;
118 profileLevel.mLevel = level;
119 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
120 mCap->mProfileLevels.push_back(profileLevel);
121 mCap->mProfileLevelsSorted.add(profileLevel);
122 }
123 }
124
addColorFormat(uint32_t format)125 void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
126 if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
127 mCap->mColorFormats.push(format);
128 mCap->mColorFormatsSorted.add(format);
129 }
130 }
131
addFlags(uint32_t flags)132 void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
133 mCap->mFlags |= flags;
134 }
135
CapabilitiesWriter(MediaCodecInfo::Capabilities * cap)136 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
137 MediaCodecInfo::Capabilities* cap) : mCap(cap) {
138 }
139
isEncoder() const140 bool MediaCodecInfo::isEncoder() const {
141 return mIsEncoder;
142 }
143
getSupportedMimes(Vector<AString> * mimes) const144 void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
145 mimes->clear();
146 for (size_t ix = 0; ix < mCaps.size(); ix++) {
147 mimes->push_back(mCaps.keyAt(ix));
148 }
149 }
150
151 const sp<MediaCodecInfo::Capabilities>
getCapabilitiesFor(const char * mime) const152 MediaCodecInfo::getCapabilitiesFor(const char *mime) const {
153 ssize_t ix = getCapabilityIndex(mime);
154 if (ix >= 0) {
155 return mCaps.valueAt(ix);
156 }
157 return NULL;
158 }
159
getCodecName() const160 const char *MediaCodecInfo::getCodecName() const {
161 return mName.c_str();
162 }
163
getOwnerName() const164 const char *MediaCodecInfo::getOwnerName() const {
165 return mOwner.c_str();
166 }
167
168 // static
FromParcel(const Parcel & parcel)169 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
170 AString name = AString::FromParcel(parcel);
171 AString owner = AString::FromParcel(parcel);
172 bool isEncoder = static_cast<bool>(parcel.readInt32());
173 sp<MediaCodecInfo> info = new MediaCodecInfo;
174 info->mName = name;
175 info->mOwner = owner;
176 info->mIsEncoder = isEncoder;
177 size_t size = static_cast<size_t>(parcel.readInt32());
178 for (size_t i = 0; i < size; i++) {
179 AString mime = AString::FromParcel(parcel);
180 sp<Capabilities> caps = Capabilities::FromParcel(parcel);
181 if (caps == NULL)
182 return NULL;
183 if (info != NULL) {
184 info->mCaps.add(mime, caps);
185 }
186 }
187 return info;
188 }
189
writeToParcel(Parcel * parcel) const190 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
191 mName.writeToParcel(parcel);
192 mOwner.writeToParcel(parcel);
193 parcel->writeInt32(mIsEncoder);
194 parcel->writeInt32(mCaps.size());
195 for (size_t i = 0; i < mCaps.size(); i++) {
196 mCaps.keyAt(i).writeToParcel(parcel);
197 mCaps.valueAt(i)->writeToParcel(parcel);
198 }
199 return OK;
200 }
201
getCapabilityIndex(const char * mime) const202 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
203 if (mime) {
204 for (size_t ix = 0; ix < mCaps.size(); ix++) {
205 if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
206 return ix;
207 }
208 }
209 }
210 return -1;
211 }
212
MediaCodecInfo()213 MediaCodecInfo::MediaCodecInfo() {
214 }
215
setName(const char * name)216 void MediaCodecInfoWriter::setName(const char* name) {
217 mInfo->mName = name;
218 }
219
setOwner(const char * owner)220 void MediaCodecInfoWriter::setOwner(const char* owner) {
221 mInfo->mOwner = owner;
222 }
223
setEncoder(bool isEncoder)224 void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
225 mInfo->mIsEncoder = isEncoder;
226 }
227
228 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
addMime(const char * mime)229 MediaCodecInfoWriter::addMime(const char *mime) {
230 ssize_t ix = mInfo->getCapabilityIndex(mime);
231 if (ix >= 0) {
232 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
233 new MediaCodecInfo::CapabilitiesWriter(
234 mInfo->mCaps.valueAt(ix).get()));
235 }
236 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
237 mInfo->mCaps.add(AString(mime), caps);
238 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
239 new MediaCodecInfo::CapabilitiesWriter(caps.get()));
240 }
241
removeMime(const char * mime)242 bool MediaCodecInfoWriter::removeMime(const char *mime) {
243 ssize_t ix = mInfo->getCapabilityIndex(mime);
244 if (ix >= 0) {
245 mInfo->mCaps.removeItemsAt(ix);
246 return true;
247 }
248 return false;
249 }
250
MediaCodecInfoWriter(MediaCodecInfo * info)251 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
252 mInfo(info) {
253 }
254
255 } // namespace android
256