• 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(), 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