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 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