blob: c45c5c3d181be8ad00f0a1d5614853ea26cbba7e [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[];
Lajos Molnard55f06f2024-04-01 14:49:28 -070039constexpr char MediaCodecInfo::Capabilities::FEATURE_DETACHED_SURFACE[];
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080040
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070041void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
42 Vector<ProfileLevel> *profileLevels) const {
43 profileLevels->clear();
44 profileLevels->appendVector(mProfileLevels);
45}
46
47void MediaCodecInfo::Capabilities::getSupportedColorFormats(
48 Vector<uint32_t> *colorFormats) const {
49 colorFormats->clear();
50 colorFormats->appendVector(mColorFormats);
51}
52
Lajos Molnar2461e0c2014-08-12 08:55:25 -070053const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070054 return mDetails;
55}
56
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080057MediaCodecInfo::Capabilities::Capabilities() {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070058 mDetails = new AMessage;
59}
60
61// static
62sp<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 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070081 sp<AMessage> details = AMessage::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -070082 if (details == NULL)
83 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070084 if (caps != NULL) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070085 caps->mDetails = details;
86 }
87 return caps;
88}
89
90status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
Colin Crossb8c35f92017-04-27 16:15:51 -070091 CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070092 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 }
Colin Crossb8c35f92017-04-27 16:15:51 -070097 CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070098 parcel->writeInt32(mColorFormats.size());
99 for (size_t i = 0; i < mColorFormats.size(); i++) {
100 parcel->writeInt32(mColorFormats.itemAt(i));
101 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700102 mDetails->writeToParcel(parcel);
103 return OK;
104}
105
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700106void MediaCodecInfo::CapabilitiesWriter::addDetail(
107 const char* key, const char* value) {
108 mCap->mDetails->setString(key, value);
109}
110
111void MediaCodecInfo::CapabilitiesWriter::addDetail(
112 const char* key, int32_t value) {
113 mCap->mDetails->setInt32(key, value);
114}
115
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800116void 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
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700124void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
125 uint32_t profile, uint32_t level) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800126 ProfileLevel profileLevel;
127 profileLevel.mProfile = profile;
128 profileLevel.mLevel = level;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700129 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
130 mCap->mProfileLevels.push_back(profileLevel);
131 mCap->mProfileLevelsSorted.add(profileLevel);
Lajos Molnar06e98362017-08-14 15:57:57 -0700132 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800133}
134
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700135void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
136 if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
137 mCap->mColorFormats.push(format);
138 mCap->mColorFormatsSorted.add(format);
Lajos Molnar06e98362017-08-14 15:57:57 -0700139 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800140}
141
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700142MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
143 MediaCodecInfo::Capabilities* cap) : mCap(cap) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800144}
145
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800146MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
147 return mAttributes;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700148}
149
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800150uint32_t MediaCodecInfo::getRank() const {
Wonsik Kim78165d32018-01-24 14:48:03 -0800151 return mRank;
152}
153
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800154void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
155 *aliases = mAliases;
156}
157
158void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
159 mediaTypes->clear();
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700160 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800161 mediaTypes->push_back(mCaps.keyAt(ix));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700162 }
163}
164
Lajos Molnar2461e0c2014-08-12 08:55:25 -0700165const sp<MediaCodecInfo::Capabilities>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800166MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
167 ssize_t ix = getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700168 if (ix >= 0) {
169 return mCaps.valueAt(ix);
170 }
171 return NULL;
172}
173
174const char *MediaCodecInfo::getCodecName() const {
175 return mName.c_str();
176}
177
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700178const char *MediaCodecInfo::getOwnerName() const {
179 return mOwner.c_str();
180}
181
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700182// static
183sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
184 AString name = AString::FromParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700185 AString owner = AString::FromParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800186 Attributes attributes = static_cast<Attributes>(parcel.readInt32());
Wonsik Kim78165d32018-01-24 14:48:03 -0800187 uint32_t rank = parcel.readUint32();
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700188 sp<MediaCodecInfo> info = new MediaCodecInfo;
189 info->mName = name;
190 info->mOwner = owner;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800191 info->mAttributes = attributes;
Wonsik Kim78165d32018-01-24 14:48:03 -0800192 info->mRank = rank;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800193 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 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700198 size_t size = static_cast<size_t>(parcel.readInt32());
199 for (size_t i = 0; i < size; i++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800200 AString mediaType = AString::FromParcel(parcel);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700201 sp<Capabilities> caps = Capabilities::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -0700202 if (caps == NULL)
203 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700204 if (info != NULL) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800205 info->mCaps.add(mediaType, caps);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700206 }
207 }
208 return info;
209}
210
211status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
212 mName.writeToParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700213 mOwner.writeToParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800214 parcel->writeInt32(mAttributes);
Wonsik Kim78165d32018-01-24 14:48:03 -0800215 parcel->writeUint32(mRank);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800216 parcel->writeInt32(mAliases.size());
217 for (const AString &alias : mAliases) {
218 alias.writeToParcel(parcel);
219 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700220 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
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800228ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
229 if (mediaType) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700230 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800231 if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700232 return ix;
233 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700234 }
235 }
236 return -1;
237}
238
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800239MediaCodecInfo::MediaCodecInfo()
240 : mAttributes((MediaCodecInfo::Attributes)0),
241 mRank(0x100) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700242}
243
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700244void MediaCodecInfoWriter::setName(const char* name) {
245 mInfo->mName = name;
246}
247
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800248void MediaCodecInfoWriter::addAlias(const char* name) {
249 mInfo->mAliases.add(name);
250}
251
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700252void MediaCodecInfoWriter::setOwner(const char* owner) {
253 mInfo->mOwner = owner;
254}
255
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800256void MediaCodecInfoWriter::setAttributes(
257 typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
258 mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700259}
260
Wonsik Kim78165d32018-01-24 14:48:03 -0800261void MediaCodecInfoWriter::setRank(uint32_t rank) {
262 mInfo->mRank = rank;
263}
264
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700265std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800266 MediaCodecInfoWriter::addMediaType(const char *mediaType) {
267 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700268 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700269 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
270 new MediaCodecInfo::CapabilitiesWriter(
271 mInfo->mCaps.valueAt(ix).get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700272 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700273 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800274 mInfo->mCaps.add(AString(mediaType), caps);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700275 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
276 new MediaCodecInfo::CapabilitiesWriter(caps.get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700277}
278
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800279bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
280 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700281 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700282 mInfo->mCaps.removeItemsAt(ix);
283 return true;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700284 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700285 return false;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700286}
287
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700288MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
289 mInfo(info) {
Lajos Molnar732c6d92014-08-14 19:54:08 -0700290}
291
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700292} // namespace android