blob: d5d1a09ffae62a08939a1c41708e7a136fe0fa43 [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
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070021#include <media/MediaCodecInfo.h>
22
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/AMessage.h>
25#include <binder/Parcel.h>
26
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070027namespace android {
28
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080029/** This redundant redeclaration is needed for C++ pre 14 */
30constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
31constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
32constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
33constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
34constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
35constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
36constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
Lajos Molnard55f06f2024-04-01 14:49:28 -070037constexpr char MediaCodecInfo::Capabilities::FEATURE_DETACHED_SURFACE[];
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080038
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070039void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
40 Vector<ProfileLevel> *profileLevels) const {
41 profileLevels->clear();
42 profileLevels->appendVector(mProfileLevels);
43}
44
45void MediaCodecInfo::Capabilities::getSupportedColorFormats(
46 Vector<uint32_t> *colorFormats) const {
47 colorFormats->clear();
48 colorFormats->appendVector(mColorFormats);
49}
50
Lajos Molnar2461e0c2014-08-12 08:55:25 -070051const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070052 return mDetails;
53}
54
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -080055MediaCodecInfo::Capabilities::Capabilities() {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070056 mDetails = new AMessage;
57}
58
59// static
60sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
61 const Parcel &parcel) {
62 sp<MediaCodecInfo::Capabilities> caps = new Capabilities();
63 size_t size = static_cast<size_t>(parcel.readInt32());
64 for (size_t i = 0; i < size; i++) {
65 ProfileLevel profileLevel;
66 profileLevel.mProfile = static_cast<uint32_t>(parcel.readInt32());
67 profileLevel.mLevel = static_cast<uint32_t>(parcel.readInt32());
68 if (caps != NULL) {
69 caps->mProfileLevels.push_back(profileLevel);
70 }
71 }
72 size = static_cast<size_t>(parcel.readInt32());
73 for (size_t i = 0; i < size; i++) {
74 uint32_t color = static_cast<uint32_t>(parcel.readInt32());
75 if (caps != NULL) {
76 caps->mColorFormats.push_back(color);
77 }
78 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070079 sp<AMessage> details = AMessage::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -070080 if (details == NULL)
81 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070082 if (caps != NULL) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070083 caps->mDetails = details;
84 }
85 return caps;
86}
87
88status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
Colin Crossb8c35f92017-04-27 16:15:51 -070089 CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070090 parcel->writeInt32(mProfileLevels.size());
91 for (size_t i = 0; i < mProfileLevels.size(); i++) {
92 parcel->writeInt32(mProfileLevels.itemAt(i).mProfile);
93 parcel->writeInt32(mProfileLevels.itemAt(i).mLevel);
94 }
Colin Crossb8c35f92017-04-27 16:15:51 -070095 CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070096 parcel->writeInt32(mColorFormats.size());
97 for (size_t i = 0; i < mColorFormats.size(); i++) {
98 parcel->writeInt32(mColorFormats.itemAt(i));
99 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700100 mDetails->writeToParcel(parcel);
101 return OK;
102}
103
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700104void MediaCodecInfo::CapabilitiesWriter::addDetail(
105 const char* key, const char* value) {
106 mCap->mDetails->setString(key, value);
107}
108
109void MediaCodecInfo::CapabilitiesWriter::addDetail(
110 const char* key, int32_t value) {
111 mCap->mDetails->setInt32(key, value);
112}
113
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800114void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
115 if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
116 ALOGD("successfully removed detail %s", key);
117 } else {
118 ALOGD("detail %s wasn't present to remove", key);
119 }
120}
121
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700122void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
123 uint32_t profile, uint32_t level) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800124 ProfileLevel profileLevel;
125 profileLevel.mProfile = profile;
126 profileLevel.mLevel = level;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700127 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
128 mCap->mProfileLevels.push_back(profileLevel);
129 mCap->mProfileLevelsSorted.add(profileLevel);
Lajos Molnar06e98362017-08-14 15:57:57 -0700130 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800131}
132
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700133void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
134 if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
135 mCap->mColorFormats.push(format);
136 mCap->mColorFormatsSorted.add(format);
Lajos Molnar06e98362017-08-14 15:57:57 -0700137 }
Lajos Molnar5b05e492016-02-04 18:57:45 -0800138}
139
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700140MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
141 MediaCodecInfo::Capabilities* cap) : mCap(cap) {
Lajos Molnar5b05e492016-02-04 18:57:45 -0800142}
143
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800144MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
145 return mAttributes;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700146}
147
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800148uint32_t MediaCodecInfo::getRank() const {
Wonsik Kim78165d32018-01-24 14:48:03 -0800149 return mRank;
150}
151
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800152void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
153 *aliases = mAliases;
154}
155
156void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
157 mediaTypes->clear();
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700158 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800159 mediaTypes->push_back(mCaps.keyAt(ix));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700160 }
161}
162
Lajos Molnar2461e0c2014-08-12 08:55:25 -0700163const sp<MediaCodecInfo::Capabilities>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800164MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
165 ssize_t ix = getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700166 if (ix >= 0) {
167 return mCaps.valueAt(ix);
168 }
169 return NULL;
170}
171
172const char *MediaCodecInfo::getCodecName() const {
173 return mName.c_str();
174}
175
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700176const char *MediaCodecInfo::getOwnerName() const {
177 return mOwner.c_str();
178}
179
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700180// static
181sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
182 AString name = AString::FromParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700183 AString owner = AString::FromParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800184 Attributes attributes = static_cast<Attributes>(parcel.readInt32());
Wonsik Kim78165d32018-01-24 14:48:03 -0800185 uint32_t rank = parcel.readUint32();
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700186 sp<MediaCodecInfo> info = new MediaCodecInfo;
187 info->mName = name;
188 info->mOwner = owner;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800189 info->mAttributes = attributes;
Wonsik Kim78165d32018-01-24 14:48:03 -0800190 info->mRank = rank;
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800191 size_t numAliases = static_cast<size_t>(parcel.readInt32());
192 for (size_t i = 0; i < numAliases; i++) {
193 AString alias = AString::FromParcel(parcel);
194 info->mAliases.add(alias);
195 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700196 size_t size = static_cast<size_t>(parcel.readInt32());
197 for (size_t i = 0; i < size; i++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800198 AString mediaType = AString::FromParcel(parcel);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700199 sp<Capabilities> caps = Capabilities::FromParcel(parcel);
Pawin Vongmasa8dab17302016-05-02 16:08:39 -0700200 if (caps == NULL)
201 return NULL;
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700202 if (info != NULL) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800203 info->mCaps.add(mediaType, caps);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700204 }
205 }
206 return info;
207}
208
209status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
210 mName.writeToParcel(parcel);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700211 mOwner.writeToParcel(parcel);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800212 parcel->writeInt32(mAttributes);
Wonsik Kim78165d32018-01-24 14:48:03 -0800213 parcel->writeUint32(mRank);
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800214 parcel->writeInt32(mAliases.size());
215 for (const AString &alias : mAliases) {
216 alias.writeToParcel(parcel);
217 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700218 parcel->writeInt32(mCaps.size());
219 for (size_t i = 0; i < mCaps.size(); i++) {
220 mCaps.keyAt(i).writeToParcel(parcel);
221 mCaps.valueAt(i)->writeToParcel(parcel);
222 }
223 return OK;
224}
225
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800226ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
227 if (mediaType) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700228 for (size_t ix = 0; ix < mCaps.size(); ix++) {
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800229 if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
Marco Nelissen89b2a0a2016-05-03 11:10:42 -0700230 return ix;
231 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700232 }
233 }
234 return -1;
235}
236
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800237MediaCodecInfo::MediaCodecInfo()
238 : mAttributes((MediaCodecInfo::Attributes)0),
239 mRank(0x100) {
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700240}
241
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700242void MediaCodecInfoWriter::setName(const char* name) {
243 mInfo->mName = name;
244}
245
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800246void MediaCodecInfoWriter::addAlias(const char* name) {
247 mInfo->mAliases.add(name);
248}
249
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700250void MediaCodecInfoWriter::setOwner(const char* owner) {
251 mInfo->mOwner = owner;
252}
253
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800254void MediaCodecInfoWriter::setAttributes(
255 typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
256 mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700257}
258
Wonsik Kim78165d32018-01-24 14:48:03 -0800259void MediaCodecInfoWriter::setRank(uint32_t rank) {
260 mInfo->mRank = rank;
261}
262
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700263std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800264 MediaCodecInfoWriter::addMediaType(const char *mediaType) {
265 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700266 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700267 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
268 new MediaCodecInfo::CapabilitiesWriter(
269 mInfo->mCaps.valueAt(ix).get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700270 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700271 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800272 mInfo->mCaps.add(AString(mediaType), caps);
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700273 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
274 new MediaCodecInfo::CapabilitiesWriter(caps.get()));
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700275}
276
Lajos Molnar8d4bdfd2018-11-13 14:23:49 -0800277bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
278 ssize_t ix = mInfo->getCapabilityIndex(mediaType);
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700279 if (ix >= 0) {
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700280 mInfo->mCaps.removeItemsAt(ix);
281 return true;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700282 }
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700283 return false;
Lajos Molnar6ff58f02014-08-11 16:46:15 -0700284}
285
Pawin Vongmasafbe70ae2017-07-27 02:21:57 -0700286MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
287 mInfo(info) {
Lajos Molnar732c6d92014-08-14 19:54:08 -0700288}
289
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700290} // namespace android