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 31 /** This redundant redeclaration is needed for C++ pre 14 */ 32 constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[]; 33 constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[]; 34 constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[]; 35 constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[]; 36 constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[]; 37 constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[]; 38 constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[]; 39 40 void MediaCodecInfo::Capabilities::getSupportedProfileLevels( 41 Vector<ProfileLevel> *profileLevels) const { 42 profileLevels->clear(); 43 profileLevels->appendVector(mProfileLevels); 44 } 45 46 void MediaCodecInfo::Capabilities::getSupportedColorFormats( 47 Vector<uint32_t> *colorFormats) const { 48 colorFormats->clear(); 49 colorFormats->appendVector(mColorFormats); 50 } 51 52 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const { 53 return mDetails; 54 } 55 56 MediaCodecInfo::Capabilities::Capabilities() { 57 mDetails = new AMessage; 58 } 59 60 // static 61 sp<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 } 80 sp<AMessage> details = AMessage::FromParcel(parcel); 81 if (details == NULL) 82 return NULL; 83 if (caps != NULL) { 84 caps->mDetails = details; 85 } 86 return caps; 87 } 88 89 status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const { 90 CHECK_LE(mProfileLevels.size(), static_cast<size_t>(INT32_MAX)); 91 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 } 96 CHECK_LE(mColorFormats.size(), static_cast<size_t>(INT32_MAX)); 97 parcel->writeInt32(mColorFormats.size()); 98 for (size_t i = 0; i < mColorFormats.size(); i++) { 99 parcel->writeInt32(mColorFormats.itemAt(i)); 100 } 101 mDetails->writeToParcel(parcel); 102 return OK; 103 } 104 105 void MediaCodecInfo::CapabilitiesWriter::addDetail( 106 const char* key, const char* value) { 107 mCap->mDetails->setString(key, value); 108 } 109 110 void MediaCodecInfo::CapabilitiesWriter::addDetail( 111 const char* key, int32_t value) { 112 mCap->mDetails->setInt32(key, value); 113 } 114 115 void 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 123 void MediaCodecInfo::CapabilitiesWriter::addProfileLevel( 124 uint32_t profile, uint32_t level) { 125 ProfileLevel profileLevel; 126 profileLevel.mProfile = profile; 127 profileLevel.mLevel = level; 128 if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) { 129 mCap->mProfileLevels.push_back(profileLevel); 130 mCap->mProfileLevelsSorted.add(profileLevel); 131 } 132 } 133 134 void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) { 135 if (mCap->mColorFormatsSorted.indexOf(format) < 0) { 136 mCap->mColorFormats.push(format); 137 mCap->mColorFormatsSorted.add(format); 138 } 139 } 140 141 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter( 142 MediaCodecInfo::Capabilities* cap) : mCap(cap) { 143 } 144 145 MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const { 146 return mAttributes; 147 } 148 149 uint32_t MediaCodecInfo::getRank() const { 150 return mRank; 151 } 152 153 void MediaCodecInfo::getAliases(Vector<AString> *aliases) const { 154 *aliases = mAliases; 155 } 156 157 void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const { 158 mediaTypes->clear(); 159 for (size_t ix = 0; ix < mCaps.size(); ix++) { 160 mediaTypes->push_back(mCaps.keyAt(ix)); 161 } 162 } 163 164 const sp<MediaCodecInfo::Capabilities> 165 MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const { 166 ssize_t ix = getCapabilityIndex(mediaType); 167 if (ix >= 0) { 168 return mCaps.valueAt(ix); 169 } 170 return NULL; 171 } 172 173 const char *MediaCodecInfo::getCodecName() const { 174 return mName.c_str(); 175 } 176 177 const char *MediaCodecInfo::getOwnerName() const { 178 return mOwner.c_str(); 179 } 180 181 // static 182 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) { 183 AString name = AString::FromParcel(parcel); 184 AString owner = AString::FromParcel(parcel); 185 Attributes attributes = static_cast<Attributes>(parcel.readInt32()); 186 uint32_t rank = parcel.readUint32(); 187 sp<MediaCodecInfo> info = new MediaCodecInfo; 188 info->mName = name; 189 info->mOwner = owner; 190 info->mAttributes = attributes; 191 info->mRank = rank; 192 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 } 197 size_t size = static_cast<size_t>(parcel.readInt32()); 198 for (size_t i = 0; i < size; i++) { 199 AString mediaType = AString::FromParcel(parcel); 200 sp<Capabilities> caps = Capabilities::FromParcel(parcel); 201 if (caps == NULL) 202 return NULL; 203 if (info != NULL) { 204 info->mCaps.add(mediaType, caps); 205 } 206 } 207 return info; 208 } 209 210 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const { 211 mName.writeToParcel(parcel); 212 mOwner.writeToParcel(parcel); 213 parcel->writeInt32(mAttributes); 214 parcel->writeUint32(mRank); 215 parcel->writeInt32(mAliases.size()); 216 for (const AString &alias : mAliases) { 217 alias.writeToParcel(parcel); 218 } 219 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 227 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const { 228 if (mediaType) { 229 for (size_t ix = 0; ix < mCaps.size(); ix++) { 230 if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) { 231 return ix; 232 } 233 } 234 } 235 return -1; 236 } 237 238 MediaCodecInfo::MediaCodecInfo() 239 : mAttributes((MediaCodecInfo::Attributes)0), 240 mRank(0x100) { 241 } 242 243 void MediaCodecInfoWriter::setName(const char* name) { 244 mInfo->mName = name; 245 } 246 247 void MediaCodecInfoWriter::addAlias(const char* name) { 248 mInfo->mAliases.add(name); 249 } 250 251 void MediaCodecInfoWriter::setOwner(const char* owner) { 252 mInfo->mOwner = owner; 253 } 254 255 void MediaCodecInfoWriter::setAttributes( 256 typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) { 257 mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes; 258 } 259 260 void MediaCodecInfoWriter::setRank(uint32_t rank) { 261 mInfo->mRank = rank; 262 } 263 264 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> 265 MediaCodecInfoWriter::addMediaType(const char *mediaType) { 266 ssize_t ix = mInfo->getCapabilityIndex(mediaType); 267 if (ix >= 0) { 268 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>( 269 new MediaCodecInfo::CapabilitiesWriter( 270 mInfo->mCaps.valueAt(ix).get())); 271 } 272 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities(); 273 mInfo->mCaps.add(AString(mediaType), caps); 274 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>( 275 new MediaCodecInfo::CapabilitiesWriter(caps.get())); 276 } 277 278 bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) { 279 ssize_t ix = mInfo->getCapabilityIndex(mediaType); 280 if (ix >= 0) { 281 mInfo->mCaps.removeItemsAt(ix); 282 return true; 283 } 284 return false; 285 } 286 287 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) : 288 mInfo(info) { 289 } 290 291 } // namespace android 292