Home | History | Annotate | Download | only in libmedia
      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