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 void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
    145     mimes->clear();
    146     for (size_t ix = 0; ix < mCaps.size(); ix++) {
    147         mimes->push_back(mCaps.keyAt(ix));
    148     }
    149 }
    150 
    151 const sp<MediaCodecInfo::Capabilities>
    152 MediaCodecInfo::getCapabilitiesFor(const char *mime) const {
    153     ssize_t ix = getCapabilityIndex(mime);
    154     if (ix >= 0) {
    155         return mCaps.valueAt(ix);
    156     }
    157     return NULL;
    158 }
    159 
    160 const char *MediaCodecInfo::getCodecName() const {
    161     return mName.c_str();
    162 }
    163 
    164 const char *MediaCodecInfo::getOwnerName() const {
    165     return mOwner.c_str();
    166 }
    167 
    168 // static
    169 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
    170     AString name = AString::FromParcel(parcel);
    171     AString owner = AString::FromParcel(parcel);
    172     bool isEncoder = static_cast<bool>(parcel.readInt32());
    173     sp<MediaCodecInfo> info = new MediaCodecInfo;
    174     info->mName = name;
    175     info->mOwner = owner;
    176     info->mIsEncoder = isEncoder;
    177     size_t size = static_cast<size_t>(parcel.readInt32());
    178     for (size_t i = 0; i < size; i++) {
    179         AString mime = AString::FromParcel(parcel);
    180         sp<Capabilities> caps = Capabilities::FromParcel(parcel);
    181         if (caps == NULL)
    182             return NULL;
    183         if (info != NULL) {
    184             info->mCaps.add(mime, caps);
    185         }
    186     }
    187     return info;
    188 }
    189 
    190 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
    191     mName.writeToParcel(parcel);
    192     mOwner.writeToParcel(parcel);
    193     parcel->writeInt32(mIsEncoder);
    194     parcel->writeInt32(mCaps.size());
    195     for (size_t i = 0; i < mCaps.size(); i++) {
    196         mCaps.keyAt(i).writeToParcel(parcel);
    197         mCaps.valueAt(i)->writeToParcel(parcel);
    198     }
    199     return OK;
    200 }
    201 
    202 ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
    203     if (mime) {
    204         for (size_t ix = 0; ix < mCaps.size(); ix++) {
    205             if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
    206                 return ix;
    207             }
    208         }
    209     }
    210     return -1;
    211 }
    212 
    213 MediaCodecInfo::MediaCodecInfo() {
    214 }
    215 
    216 void MediaCodecInfoWriter::setName(const char* name) {
    217     mInfo->mName = name;
    218 }
    219 
    220 void MediaCodecInfoWriter::setOwner(const char* owner) {
    221     mInfo->mOwner = owner;
    222 }
    223 
    224 void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
    225     mInfo->mIsEncoder = isEncoder;
    226 }
    227 
    228 std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
    229         MediaCodecInfoWriter::addMime(const char *mime) {
    230     ssize_t ix = mInfo->getCapabilityIndex(mime);
    231     if (ix >= 0) {
    232         return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
    233                 new MediaCodecInfo::CapabilitiesWriter(
    234                 mInfo->mCaps.valueAt(ix).get()));
    235     }
    236     sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
    237     mInfo->mCaps.add(AString(mime), caps);
    238     return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
    239             new MediaCodecInfo::CapabilitiesWriter(caps.get()));
    240 }
    241 
    242 bool MediaCodecInfoWriter::removeMime(const char *mime) {
    243     ssize_t ix = mInfo->getCapabilityIndex(mime);
    244     if (ix >= 0) {
    245         mInfo->mCaps.removeItemsAt(ix);
    246         return true;
    247     }
    248     return false;
    249 }
    250 
    251 MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
    252     mInfo(info) {
    253 }
    254 
    255 }  // namespace android
    256