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 void MediaCodecInfo::Capabilities::getSupportedProfileLevels( 32 Vector<ProfileLevel> *profileLevels) const { 33 profileLevels->clear(); 34 profileLevels->appendVector(mProfileLevels); 35 } 36 37 void MediaCodecInfo::Capabilities::getSupportedColorFormats( 38 Vector<uint32_t> *colorFormats) const { 39 colorFormats->clear(); 40 colorFormats->appendVector(mColorFormats); 41 } 42 43 uint32_t MediaCodecInfo::Capabilities::getFlags() const { 44 return mFlags; 45 } 46 47 const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const { 48 return mDetails; 49 } 50 51 MediaCodecInfo::Capabilities::Capabilities() 52 : mFlags(0) { 53 mDetails = new AMessage; 54 } 55 56 // static 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 87 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 104 void MediaCodecInfo::CapabilitiesWriter::addDetail( 105 const char* key, const char* value) { 106 mCap->mDetails->setString(key, value); 107 } 108 109 void MediaCodecInfo::CapabilitiesWriter::addDetail( 110 const char* key, int32_t value) { 111 mCap->mDetails->setInt32(key, value); 112 } 113 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 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 132 void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) { 133 mCap->mFlags |= flags; 134 } 135 136 MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter( 137 MediaCodecInfo::Capabilities* cap) : mCap(cap) { 138 } 139 140 bool MediaCodecInfo::isEncoder() const { 141 return mIsEncoder; 142 } 143 144 uint32_t MediaCodecInfo::rank() const { 145 return mRank; 146 } 147 148 void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const { 149 mimes->clear(); 150 for (size_t ix = 0; ix < mCaps.size(); ix++) { 151 mimes->push_back(mCaps.keyAt(ix)); 152 } 153 } 154 155 const sp<MediaCodecInfo::Capabilities> 156 MediaCodecInfo::getCapabilitiesFor(const char *mime) const { 157 ssize_t ix = getCapabilityIndex(mime); 158 if (ix >= 0) { 159 return mCaps.valueAt(ix); 160 } 161 return NULL; 162 } 163 164 const char *MediaCodecInfo::getCodecName() const { 165 return mName.c_str(); 166 } 167 168 const char *MediaCodecInfo::getOwnerName() const { 169 return mOwner.c_str(); 170 } 171 172 // static 173 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) { 174 AString name = AString::FromParcel(parcel); 175 AString owner = AString::FromParcel(parcel); 176 bool isEncoder = static_cast<bool>(parcel.readInt32()); 177 uint32_t rank = parcel.readUint32(); 178 sp<MediaCodecInfo> info = new MediaCodecInfo; 179 info->mName = name; 180 info->mOwner = owner; 181 info->mIsEncoder = isEncoder; 182 info->mRank = rank; 183 size_t size = static_cast<size_t>(parcel.readInt32()); 184 for (size_t i = 0; i < size; i++) { 185 AString mime = AString::FromParcel(parcel); 186 sp<Capabilities> caps = Capabilities::FromParcel(parcel); 187 if (caps == NULL) 188 return NULL; 189 if (info != NULL) { 190 info->mCaps.add(mime, caps); 191 } 192 } 193 return info; 194 } 195 196 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const { 197 mName.writeToParcel(parcel); 198 mOwner.writeToParcel(parcel); 199 parcel->writeInt32(mIsEncoder); 200 parcel->writeUint32(mRank); 201 parcel->writeInt32(mCaps.size()); 202 for (size_t i = 0; i < mCaps.size(); i++) { 203 mCaps.keyAt(i).writeToParcel(parcel); 204 mCaps.valueAt(i)->writeToParcel(parcel); 205 } 206 return OK; 207 } 208 209 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const { 210 if (mime) { 211 for (size_t ix = 0; ix < mCaps.size(); ix++) { 212 if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) { 213 return ix; 214 } 215 } 216 } 217 return -1; 218 } 219 220 MediaCodecInfo::MediaCodecInfo() : mRank(0x100) { 221 } 222 223 void MediaCodecInfoWriter::setName(const char* name) { 224 mInfo->mName = name; 225 } 226 227 void MediaCodecInfoWriter::setOwner(const char* owner) { 228 mInfo->mOwner = owner; 229 } 230 231 void MediaCodecInfoWriter::setEncoder(bool isEncoder) { 232 mInfo->mIsEncoder = isEncoder; 233 } 234 235 void MediaCodecInfoWriter::setRank(uint32_t rank) { 236 mInfo->mRank = rank; 237 } 238 239 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> 240 MediaCodecInfoWriter::addMime(const char *mime) { 241 ssize_t ix = mInfo->getCapabilityIndex(mime); 242 if (ix >= 0) { 243 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>( 244 new MediaCodecInfo::CapabilitiesWriter( 245 mInfo->mCaps.valueAt(ix).get())); 246 } 247 sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities(); 248 mInfo->mCaps.add(AString(mime), caps); 249 return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>( 250 new MediaCodecInfo::CapabilitiesWriter(caps.get())); 251 } 252 253 bool MediaCodecInfoWriter::removeMime(const char *mime) { 254 ssize_t ix = mInfo->getCapabilityIndex(mime); 255 if (ix >= 0) { 256 mInfo->mCaps.removeItemsAt(ix); 257 return true; 258 } 259 return false; 260 } 261 262 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) : 263 mInfo(info) { 264 } 265 266 } // namespace android 267