blob: 86ad99778cdcce77c92c5446d8ead8371afcef94 [file] [log] [blame]
Lajos Molnar60b1c0e2014-08-06 16:55:46 -07001/*
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
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070029namespace android {
30
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080031/** This redundant redeclaration is needed for C++ pre 14 */
32constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
33constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
34constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
35constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
36constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
37constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
38constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
39
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070040void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
41 Vector<ProfileLevel> *profileLevels) const {
42 profileLevels->clear();
43 profileLevels->appendVector(mProfileLevels);
44}
45
46void MediaCodecInfo::Capabilities::getSupportedColorFormats(
47 Vector<uint32_t> *colorFormats) const {
48 colorFormats->clear();
49 colorFormats->appendVector(mColorFormats);
50}
51
Lajos Molnar2461e0c2014-08-12 08:55:25 -070052const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070053 return mDetails;
54}
55
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080056MediaCodecInfo::Capabilities::Capabilities() {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070057 mDetails = new AMessage;
58}
59
60// static
61sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
62 const Parcel &parcel) {
63 sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
64 size_t size = static_cast<size_t>(parcel.readInt32());
65 for (size_t i = 0; i < size; i++) {
66 ProfileLevel profileLevel;
67 profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
68 profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
69 if (caps != NULL) {
70 caps->mProfileLevels.push_back(profileLevel);
71 }
72 }
73 size = static_cast<size_t>(parcel.readInt32());
74 for (size_t i = 0; i < size; i++) {
75 uint32_t color = static_cast<uint32_t>(parcel.readInt32());
76 if (caps != NULL) {
77 caps->mColorFormats.push_back(color);
78 }
79 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070080 sp<AMessage> details = AMessage::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -070081 if (details == NULL)
82 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070083 if (caps != NULL) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070084 caps->mDetails = details;
85 }
86 return caps;
87}
88
89status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
Colin Crossb8c35f92017-04-27 16:15:51 -070090 CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070091 parcel->writeInt32(mProfileLevels.size());
92 for (size_t i = 0; i < mProfileLevels.size(); i++) {
93 parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
94 parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
95 }
Colin Crossb8c35f92017-04-27 16:15:51 -070096 CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070097 parcel->writeInt32(mColorFormats.size());
98 for (size_t i = 0; i < mColorFormats.size(); i++) {
99 parcel->writeInt32(mColorFormats.itemAt(i));
100 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700101 mDetails->writeToParcel(parcel);
102 return OK;
103}
104
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700105void MediaCodecInfo::CapabilitiesWriter::addDetail(
106 const char* key, const char* value) {
107 mCap->mDetails->setString(key, value);
108}
109
110void MediaCodecInfo::CapabilitiesWriter::addDetail(
111 const char* key, int32_t value) {
112 mCap->mDetails->setInt32(key, value);
113}
114
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800115void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
116 if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
117 ALOGD("successfully removed detail %s", key);
118 } else {
119 ALOGD("detail %s wasn't present to remove", key);
120 }
121}
122
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700123void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
124 uint32_t profile, uint32_t level) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800125 ProfileLevel profileLevel;
126 profileLevel.mProfile = profile;
127 profileLevel.mLevel = level;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700128 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
129 mCap->mProfileLevels.push_back(profileLevel);
130 mCap->mProfileLevelsSorted.add(profileLevel);
Lajos Molnar06e98362017-08-14 15:57:57 -0700131 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800132}
133
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700134void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
135 if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
136 mCap->mColorFormats.push(format);
137 mCap->mColorFormatsSorted.add(format);
Lajos Molnar06e98362017-08-14 15:57:57 -0700138 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800139}
140
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700141MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
142 MediaCodecInfo::Capabilities* cap) : mCap(cap) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800143}
144
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800145MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
146 return mAttributes;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700147}
148
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800149uint32_t MediaCodecInfo::getRank() const {
Wonsik Kim78165d32018-01-24 14:48:03 -0800150 return mRank;
151}
152
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800153void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
154 *aliases = mAliases;
155}
156
157void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
158 mediaTypes->clear();
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700159 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800160 mediaTypes->push_back(mCaps.keyAt(ix));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700161 }
162}
163
Lajos Molnar2461e0c2014-08-12 08:55:25 -0700164const sp<MediaCodecInfo::Capabilities>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800165MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
166 ssize_t ix = getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700167 if (ix >= 0) {
168 return mCaps.valueAt(ix);
169 }
170 return NULL;
171}
172
173const char *MediaCodecInfo::getCodecName() const {
174 return mName.c_str();
175}
176
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700177const char *MediaCodecInfo::getOwnerName() const {
178 return mOwner.c_str();
179}
180
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700181// static
182sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
183 AString name = AString::FromParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700184 AString owner = AString::FromParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800185 Attributes attributes = static_cast<Attributes>(parcel.readInt32());
Wonsik Kim78165d32018-01-24 14:48:03 -0800186 uint32_t rank = parcel.readUint32();
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700187 sp<MediaCodecInfo> info = new MediaCodecInfo;
188 info->mName = name;
189 info->mOwner = owner;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800190 info->mAttributes = attributes;
Wonsik Kim78165d32018-01-24 14:48:03 -0800191 info->mRank = rank;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800192 size_t numAliases = static_cast<size_t>(parcel.readInt32());
193 for (size_t i = 0; i < numAliases; i++) {
194 AString alias = AString::FromParcel(parcel);
195 info->mAliases.add(alias);
196 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700197 size_t size = static_cast<size_t>(parcel.readInt32());
198 for (size_t i = 0; i < size; i++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800199 AString mediaType = AString::FromParcel(parcel);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700200 sp<Capabilities> caps = Capabilities::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -0700201 if (caps == NULL)
202 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700203 if (info != NULL) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800204 info->mCaps.add(mediaType, caps);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700205 }
206 }
207 return info;
208}
209
210status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
211 mName.writeToParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700212 mOwner.writeToParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800213 parcel->writeInt32(mAttributes);
Wonsik Kim78165d32018-01-24 14:48:03 -0800214 parcel->writeUint32(mRank);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800215 parcel->writeInt32(mAliases.size());
216 for (const AString &alias : mAliases) {
217 alias.writeToParcel(parcel);
218 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700219 parcel->writeInt32(mCaps.size());
220 for (size_t i = 0; i < mCaps.size(); i++) {
221 mCaps.keyAt(i).writeToParcel(parcel);
222 mCaps.valueAt(i)->writeToParcel(parcel);
223 }
224 return OK;
225}
226
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800227ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
228 if (mediaType) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700229 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800230 if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700231 return ix;
232 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700233 }
234 }
235 return -1;
236}
237
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800238MediaCodecInfo::MediaCodecInfo()
239 : mAttributes((MediaCodecInfo::Attributes)0),
240 mRank(0x100) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700241}
242
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700243void MediaCodecInfoWriter::setName(const char* name) {
244 mInfo->mName = name;
245}
246
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800247void MediaCodecInfoWriter::addAlias(const char* name) {
248 mInfo->mAliases.add(name);
249}
250
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700251void MediaCodecInfoWriter::setOwner(const char* owner) {
252 mInfo->mOwner = owner;
253}
254
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800255void MediaCodecInfoWriter::setAttributes(
256 typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
257 mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700258}
259
Wonsik Kim78165d32018-01-24 14:48:03 -0800260void MediaCodecInfoWriter::setRank(uint32_t rank) {
261 mInfo->mRank = rank;
262}
263
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700264std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800265 MediaCodecInfoWriter::addMediaType(const char *mediaType) {
266 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700267 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700268 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
269 new MediaCodecInfo::CapabilitiesWriter(
270 mInfo->mCaps.valueAt(ix).get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700271 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700272 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800273 mInfo->mCaps.add(AString(mediaType), caps);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700274 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
275 new MediaCodecInfo::CapabilitiesWriter(caps.get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700276}
277
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800278bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
279 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700280 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700281 mInfo->mCaps.removeItemsAt(ix);
282 return true;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700283 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700284 return false;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700285}
286
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700287MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
288 mInfo(info) {
Lajos Molnar732c6d92014-08-14 19:54:08 -0700289}
290
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700291} // namespace android