Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5b3d4db authored by Songyue Han's avatar Songyue Han Committed by Automerger Merge Worker
Browse files

Merge "CodecCapabilities: Port CodecCapabilities from Java to native." into...

Merge "CodecCapabilities: Port CodecCapabilities from Java to native." into main am: 7b5b22a9 am: 640a0c23

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/3063607



Change-Id: I9f6cf6836f84dabd12bf5ad392e326b658a363af
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents dda24503 640a0c23
Loading
Loading
Loading
Loading
+385 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CodecCapabilities"

#include <android-base/strings.h>
#include <utils/Log.h>
#include <media/CodecCapabilities.h>
#include <media/CodecCapabilitiesUtils.h>
@@ -25,6 +26,58 @@

namespace android {

static const int32_t HEVCHighTierLevels =
        HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 |
        HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 |
        HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 |
        HEVCHighTierLevel62;

static const int32_t DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
static const int32_t MAX_SUPPORTED_INSTANCES_LIMIT = 256;

// must not contain KEY_PROFILE
static const std::set<std::pair<std::string, AMessage::Type>> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = {
    // We don't set level-specific limits for audio codecs today. Key candidates would
    // be sample rate, bit rate or channel count.
    // MediaFormat.KEY_SAMPLE_RATE,
    // MediaFormat.KEY_CHANNEL_COUNT,
    // MediaFormat.KEY_BIT_RATE,
    { KEY_MIME, AMessage::kTypeString }
};

// CodecCapabilities Features
static const std::vector<Feature> DECODER_FEATURES = {
    Feature(FEATURE_AdaptivePlayback, (1 << 0), true),
    Feature(FEATURE_SecurePlayback,   (1 << 1), false),
    Feature(FEATURE_TunneledPlayback, (1 << 2), false),
    Feature(FEATURE_PartialFrame,     (1 << 3), false),
    Feature(FEATURE_FrameParsing,     (1 << 4), false),
    Feature(FEATURE_MultipleFrames,   (1 << 5), false),
    Feature(FEATURE_DynamicTimestamp, (1 << 6), false),
    Feature(FEATURE_LowLatency,       (1 << 7), true),
    // feature to exclude codec from REGULAR codec list
    Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
};
static const std::vector<Feature> ENCODER_FEATURES = {
    Feature(FEATURE_IntraRefresh, (1 << 0), false),
    Feature(FEATURE_MultipleFrames, (1 << 1), false),
    Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
    Feature(FEATURE_QpBounds, (1 << 3), false),
    Feature(FEATURE_EncodingStatistics, (1 << 4), false),
    Feature(FEATURE_HdrEditing, (1 << 5), false),
    // feature to exclude codec from REGULAR codec list
    Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
};

// must not contain KEY_PROFILE
static const std::set<std::pair<std::string, AMessage::Type>> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = {
    { KEY_WIDTH, AMessage::kTypeInt32 },
    { KEY_HEIGHT, AMessage::kTypeInt32 },
    { KEY_FRAME_RATE, AMessage::kTypeInt32 },
    { KEY_BIT_RATE, AMessage::kTypeInt32 },
    { KEY_MIME, AMessage::kTypeString }
};

bool CodecCapabilities::SupportsBitrate(Range<int32_t> bitrateRange,
        const sp<AMessage> &format) {
    // consider max bitrate over average bitrate for support
@@ -46,6 +99,212 @@ bool CodecCapabilities::SupportsBitrate(Range<int32_t> bitrateRange,
    return true;
}

bool CodecCapabilities::isFeatureSupported(const std::string &name) const {
    return mFeaturesSupported.contains(name);
}

bool CodecCapabilities::isFeatureRequired(const std::string &name) const {
    return mFeaturesRequired.contains(name);
}

std::vector<std::string> CodecCapabilities::validFeatures() const {
    std::vector<std::string> res;
    for (const Feature& feature : getValidFeatures()) {
        if (!feature.mInternal) {
            res.push_back(feature.mName);
        }
    }
    return res;
}

std::vector<Feature> CodecCapabilities::getValidFeatures() const {
    if (isEncoder()) {
        return ENCODER_FEATURES;
    } else {
        return DECODER_FEATURES;
    }
}

bool CodecCapabilities::isRegular() const {
    // regular codecs only require default features
    std::vector<Feature> features = getValidFeatures();
    return std::all_of(features.begin(), features.end(),
            [this](Feature feat){ return (feat.mDefault || !isFeatureRequired(feat.mName)); });
}

bool CodecCapabilities::isFormatSupported(const sp<AMessage> &format) const {
    AString mediaType;
    format->findString(KEY_MIME, &mediaType);
    // mediaType must match if present
    if (!base::EqualsIgnoreCase(mMediaType, mediaType.c_str())) {
        return false;
    }

    // check feature support
    for (Feature feat: getValidFeatures()) {
        if (feat.mInternal) {
            continue;
        }

        int32_t yesNo;
        std::string key = KEY_FEATURE_;
        key = key + feat.mName;
        if (format->findInt32(key.c_str(), &yesNo)) {
            continue;
        }
        if ((yesNo == 1 && !isFeatureSupported(feat.mName)) ||
                (yesNo == 0 && isFeatureRequired(feat.mName))) {
            return false;
        }
    }

    int32_t profile;
    if (format->findInt32(KEY_PROFILE, &profile)) {
        int32_t level = -1;
        format->findInt32(KEY_LEVEL, &level);
        if (!supportsProfileLevel(profile, level)) {
            return false;
        }

        // If we recognize this profile, check that this format is supported by the
        // highest level supported by the codec for that profile. (Ignore specified
        // level beyond the above profile/level check as level is only used as a
        // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
        // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
        // 1080p format is not supported even if codec supports Main Profile Level High,
        // as Simple Profile does not support 1080p.
        int32_t maxLevel = 0;
        for (ProfileLevel pl : mProfileLevels) {
            if (pl.mProfile == profile && pl.mLevel > maxLevel) {
                // H.263 levels are not completely ordered:
                // Level45 support only implies Level10 support
                if (!base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_H263)
                        || pl.mLevel != H263Level45
                        || maxLevel == H263Level10) {
                    maxLevel = pl.mLevel;
                }
            }
        }
        std::shared_ptr<CodecCapabilities> levelCaps
                = CreateFromProfileLevel(mMediaType, profile, maxLevel);
        // We must remove the profile from this format otherwise levelCaps.isFormatSupported
        // will get into this same condition and loop forever. Furthermore, since levelCaps
        // does not contain features and bitrate specific keys, keep only keys relevant for
        // a level check.
        sp<AMessage> levelCriticalFormat = new AMessage;

        // critical keys will always contain KEY_MIME, but should also contain others to be
        // meaningful
        if ((isVideo() || isAudio()) && levelCaps != nullptr) {
            const std::set<std::pair<std::string, AMessage::Type>> criticalKeys =
                isVideo() ? VIDEO_LEVEL_CRITICAL_FORMAT_KEYS : AUDIO_LEVEL_CRITICAL_FORMAT_KEYS;
            for (std::pair<std::string, AMessage::Type> key : criticalKeys) {
                if (format->contains(key.first.c_str())) {
                    // AMessage::ItemData value = format->findItem(key.c_str());
                    // levelCriticalFormat->setItem(key.c_str(), value);
                    switch (key.second) {
                        case AMessage::kTypeInt32: {
                            int32_t value;
                            format->findInt32(key.first.c_str(), &value);
                            levelCriticalFormat->setInt32(key.first.c_str(), value);
                            break;
                        }
                        case AMessage::kTypeString: {
                            AString value;
                            format->findString(key.first.c_str(), &value);
                            levelCriticalFormat->setString(key.first.c_str(), value);
                            break;
                        }
                        default:
                            ALOGE("Unsupported type");
                    }
                }
            }
            if (!levelCaps->isFormatSupported(levelCriticalFormat)) {
                return false;
            }
        }
    }
    if (mAudioCaps && !mAudioCaps->supportsFormat(format)) {
        return false;
    }
    if (mVideoCaps && !mVideoCaps->supportsFormat(format)) {
        return false;
    }
    if (mEncoderCaps && !mEncoderCaps->supportsFormat(format)) {
        return false;
    }
    return true;
}

bool CodecCapabilities::supportsProfileLevel(int32_t profile, int32_t level) const {
    for (ProfileLevel pl: mProfileLevels) {
        if (pl.mProfile != profile) {
            continue;
        }

        // No specific level requested
        if (level == -1) {
            return true;
        }

        // AAC doesn't use levels
        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
            return true;
        }

        // DTS doesn't use levels
        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS)
                || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_HD)
                || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_UHD)) {
            return true;
        }

        // H.263 levels are not completely ordered:
        // Level45 support only implies Level10 support
        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_H263)) {
            if (pl.mLevel != level && pl.mLevel == H263Level45
                    && level > H263Level10) {
                continue;
            }
        }

        // MPEG4 levels are not completely ordered:
        // Level1 support only implies Level0 (and not Level0b) support
        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_MPEG4)) {
            if (pl.mLevel != level && pl.mLevel == MPEG4Level1
                    && level > MPEG4Level0) {
                continue;
            }
        }

        // HEVC levels incorporate both tiers and levels. Verify tier support.
        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_HEVC)) {
            bool supportsHighTier =
                (pl.mLevel & HEVCHighTierLevels) != 0;
            bool checkingHighTier = (level & HEVCHighTierLevels) != 0;
            // high tier levels are only supported by other high tier levels
            if (checkingHighTier && !supportsHighTier) {
                continue;
            }
        }

        if (pl.mLevel >= level) {
            // if we recognize the listed profile/level, we must also recognize the
            // profile/level arguments.
            if (CreateFromProfileLevel(mMediaType, profile, pl.mLevel) != nullptr) {
                return CreateFromProfileLevel(mMediaType, profile, level) != nullptr;
            }
            return true;
        }
    }
    return false;
}

sp<AMessage> CodecCapabilities::getDefaultFormat() const {
    return mDefaultFormat;
}

const std::string& CodecCapabilities::getMediaType() {
    return mMediaType;
}
@@ -54,4 +313,130 @@ const std::vector<ProfileLevel>& CodecCapabilities::getProfileLevels() {
    return mProfileLevels;
}

std::vector<uint32_t> CodecCapabilities::getColorFormats() const {
    return mColorFormats;
}

int32_t CodecCapabilities::getMaxSupportedInstances() const {
    return mMaxSupportedInstances;
}

bool CodecCapabilities::isAudio() const {
    return mAudioCaps != nullptr;
}

std::shared_ptr<AudioCapabilities>
        CodecCapabilities::getAudioCapabilities() const {
    return mAudioCaps;
}

bool CodecCapabilities::isEncoder() const {
    return mEncoderCaps != nullptr;
}

std::shared_ptr<EncoderCapabilities>
        CodecCapabilities::getEncoderCapabilities() const {
    return mEncoderCaps;
}

bool CodecCapabilities::isVideo() const {
    return mVideoCaps != nullptr;
}

std::shared_ptr<VideoCapabilities> CodecCapabilities::getVideoCapabilities() const {
    return mVideoCaps;
}

// static
std::shared_ptr<CodecCapabilities> CodecCapabilities::CreateFromProfileLevel(
        std::string mediaType, int32_t profile, int32_t level, int32_t maxConcurrentInstances) {
    ProfileLevel pl;
    pl.mProfile = profile;
    pl.mLevel = level;
    sp<AMessage> defaultFormat = new AMessage;
    defaultFormat->setString(KEY_MIME, mediaType.c_str());

    std::vector<ProfileLevel> pls;
    pls.push_back(pl);
    std::vector<uint32_t> colFmts;
    sp<AMessage> capabilitiesInfo = new AMessage;
    std::shared_ptr<CodecCapabilities> ret(new CodecCapabilities());
    ret->init(pls, colFmts, true /* encoder */, defaultFormat, capabilitiesInfo,
            maxConcurrentInstances);
    if (ret->getErrors() != 0) {
        return nullptr;
    }
    return ret;
}

void CodecCapabilities::init(std::vector<ProfileLevel> profLevs, std::vector<uint32_t> colFmts,
        bool encoder, sp<AMessage> &defaultFormat, sp<AMessage> &capabilitiesInfo,
        int32_t maxConcurrentInstances) {
    mColorFormats = colFmts;
    mDefaultFormat = defaultFormat;
    mCapabilitiesInfo = capabilitiesInfo;

    AString mediaTypeAStr;
    mDefaultFormat->findString(KEY_MIME, &mediaTypeAStr);
    mMediaType = mediaTypeAStr.c_str();

    /* VP9 introduced profiles around 2016, so some VP9 codecs may not advertise any
       supported profiles. Determine the level for them using the info they provide. */
    if (profLevs.size() == 0 && mMediaType == MIMETYPE_VIDEO_VP9) {
        ProfileLevel profLev;
        profLev.mProfile = VP9Profile0;
        profLev.mLevel = VideoCapabilities::EquivalentVP9Level(capabilitiesInfo);
        profLevs.push_back(profLev);
    }
    mProfileLevels = profLevs;

    if (mediaTypeAStr.startsWithIgnoreCase("audio/")) {
        mAudioCaps = AudioCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
        mAudioCaps->getDefaultFormat(mDefaultFormat);
    } else if (mediaTypeAStr.startsWithIgnoreCase("video/")
            || mediaTypeAStr.equalsIgnoreCase(MIMETYPE_IMAGE_ANDROID_HEIC)) {
        mVideoCaps = VideoCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
    }

    if (encoder) {
        mEncoderCaps = EncoderCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
        mEncoderCaps->getDefaultFormat(mDefaultFormat);
    }

    mMaxSupportedInstances = maxConcurrentInstances > 0
            ? maxConcurrentInstances : DEFAULT_MAX_SUPPORTED_INSTANCES;

    int32_t maxInstances = mMaxSupportedInstances;
    capabilitiesInfo->findInt32("max-concurrent-instances", &maxInstances);
    mMaxSupportedInstances =
            Range(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);

    mFeaturesRequired.clear();
    mFeaturesSupported.clear();
    for (Feature feat: getValidFeatures()) {
        std::string key = KEY_FEATURE_;
        key = key + feat.mName;
        int yesNo = -1;
        if (!capabilitiesInfo->findInt32(key.c_str(), &yesNo)) {
            continue;
        }
        if (yesNo > 0) {
            mFeaturesRequired.insert(feat.mName);
        }
        mFeaturesSupported.insert(feat.mName);
        if (!feat.mInternal) {
            mDefaultFormat->setInt32(key.c_str(), 1);
        }
    }
}

int32_t CodecCapabilities::getErrors() const {
    if (mAudioCaps) {
        return mAudioCaps->mError;
    } else if (mVideoCaps) {
        return mVideoCaps->mError;
    }
    return 0;
}

}  // namespace android
 No newline at end of file
+216 −0
Original line number Diff line number Diff line
@@ -39,6 +39,26 @@ struct CodecCapabilities {
    static bool SupportsBitrate(Range<int32_t> bitrateRange,
            const sp<AMessage> &format);

    /**
     * Retrieve the codec capabilities for a certain {@code mime type}, {@code
     * profile} and {@code level}.  If the type, or profile-level combination
     * is not understood by the framework, it returns null.
     * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this
     * method without calling any method of the {@link MediaCodecList} class beforehand
     * results in a {@link NullPointerException}.</p>
     */
    static std::shared_ptr<CodecCapabilities> CreateFromProfileLevel(std::string mediaType,
                int32_t profile, int32_t level, int32_t maxConcurrentInstances = -1);

    CodecCapabilities() {};

    /**
     * Init CodecCapabilities with settings.
     */
    void init(std::vector<ProfileLevel> profLevs, std::vector<uint32_t> colFmts, bool encoder,
            sp<AMessage> &defaultFormat, sp<AMessage> &capabilitiesInfo,
            int32_t maxConcurrentInstances = 0);

    /**
     * Returns the media type for which this codec-capability object was created.
     */
@@ -49,13 +69,209 @@ struct CodecCapabilities {
     */
    const std::vector<ProfileLevel>& getProfileLevels();

    /**
     * Returns the supported color formats.
     */
    std::vector<uint32_t> getColorFormats() const;

    /**
     * Returns a media format with default values for configurations that have defaults.
     */
    sp<AMessage> getDefaultFormat() const;

    /**
     * Returns the max number of the supported concurrent codec instances.
     * <p>
     * This is a hint for an upper bound. Applications should not expect to successfully
     * operate more instances than the returned value, but the actual number of
     * concurrently operable instances may be less as it depends on the available
     * resources at time of use.
     */
    int32_t getMaxSupportedInstances() const;

    /**
     * Returns the audio capabilities or {@code null} if this is not an audio codec.
     */
    std::shared_ptr<AudioCapabilities> getAudioCapabilities() const;

    /**
     * Returns the video capabilities or {@code null} if this is not a video codec.
     */
    std::shared_ptr<VideoCapabilities> getVideoCapabilities() const;

    /**
     * Returns the encoding capabilities or {@code null} if this is not an encoder.
     */
    std::shared_ptr<EncoderCapabilities> getEncoderCapabilities() const;

    std::vector<std::string> validFeatures() const;

    /**
     * Query codec feature capabilities.
     * <p>
     * These features are supported to be used by the codec.  These
     * include optional features that can be turned on, as well as
     * features that are always on.
     */
    bool isFeatureSupported(const std::string &name) const;

    /**
     * Query codec feature requirements.
     * <p>
     * These features are required to be used by the codec, and as such,
     * they are always turned on.
     */
    bool isFeatureRequired(const std::string &name) const;

    bool isRegular() const;

    /**
    * Query whether codec supports a given {@link MediaFormat}.
    *
    * <p class=note>
    * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
    * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
    * frame rate}. Use
    * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
    * to clear any existing frame rate setting in the format.
    * <p>
    *
    * The following table summarizes the format keys considered by this method.
    * This is especially important to consider when targeting a higher SDK version than the
    * minimum SDK version, as this method will disregard some keys on devices below the target
    * SDK version.
    *
    * <table style="width: 0%">
    *  <thead>
    *   <tr>
    *    <th rowspan=3>OS Version(s)</th>
    *    <td colspan=3>{@code MediaFormat} keys considered for</th>
    *   </tr><tr>
    *    <th>Audio Codecs</th>
    *    <th>Video Codecs</th>
    *    <th>Encoders</th>
    *   </tr>
    *  </thead>
    *  <tbody>
    *   <tr>
    *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
    *    <td rowspan=3>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
    *        {@link MediaFormat#KEY_SAMPLE_RATE},<br>
    *        {@link MediaFormat#KEY_CHANNEL_COUNT},</td>
    *    <td>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
    *        {@link CodecCapabilities#FEATURE_AdaptivePlayback}<sup>D</sup>,<br>
    *        {@link CodecCapabilities#FEATURE_SecurePlayback}<sup>D</sup>,<br>
    *        {@link CodecCapabilities#FEATURE_TunneledPlayback}<sup>D</sup>,<br>
    *        {@link MediaFormat#KEY_WIDTH},<br>
    *        {@link MediaFormat#KEY_HEIGHT},<br>
    *        <strong>no</strong> {@code KEY_FRAME_RATE}</td>
    *    <td rowspan=10>as to the left, plus<br>
    *        {@link MediaFormat#KEY_BITRATE_MODE},<br>
    *        {@link MediaFormat#KEY_PROFILE}
    *        (and/or {@link MediaFormat#KEY_AAC_PROFILE}<sup>~</sup>),<br>
    *        <!-- {link MediaFormat#KEY_QUALITY},<br> -->
    *        {@link MediaFormat#KEY_COMPLEXITY}
    *        (and/or {@link MediaFormat#KEY_FLAC_COMPRESSION_LEVEL}<sup>~</sup>)</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
    *    <td rowspan=2>as above, plus<br>
    *        {@link MediaFormat#KEY_FRAME_RATE}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
    *    <td rowspan=2>as above, plus<br>
    *        {@link MediaFormat#KEY_PROFILE},<br>
    *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
    *        {@link MediaFormat#KEY_BIT_RATE}</td>
    *    <td rowspan=2>as above, plus<br>
    *        {@link MediaFormat#KEY_PROFILE},<br>
    *        {@link MediaFormat#KEY_LEVEL}<sup>+</sup>,<br>
    *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
    *        {@link MediaFormat#KEY_BIT_RATE},<br>
    *        {@link CodecCapabilities#FEATURE_IntraRefresh}<sup>E</sup></td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#N_MR1}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#O}</td>
    *    <td rowspan=3 colspan=2>as above, plus<br>
    *        {@link CodecCapabilities#FEATURE_PartialFrame}<sup>D</sup></td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#O_MR1}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#P}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#Q}</td>
    *    <td colspan=2>as above, plus<br>
    *        {@link CodecCapabilities#FEATURE_FrameParsing}<sup>D</sup>,<br>
    *        {@link CodecCapabilities#FEATURE_MultipleFrames},<br>
    *        {@link CodecCapabilities#FEATURE_DynamicTimestamp}</td>
    *   </tr><tr>
    *    <td>{@link android.os.Build.VERSION_CODES#R}</td>
    *    <td colspan=2>as above, plus<br>
    *        {@link CodecCapabilities#FEATURE_LowLatency}<sup>D</sup></td>
    *   </tr>
    *   <tr>
    *    <td colspan=4>
    *     <p class=note><strong>Notes:</strong><br>
    *      *: must be specified; otherwise, method returns {@code false}.<br>
    *      +: method does not verify that the format parameters are supported
    *      by the specified level.<br>
    *      D: decoders only<br>
    *      E: encoders only<br>
    *      ~: if both keys are provided values must match
    *    </td>
    *   </tr>
    *  </tbody>
    * </table>
    *
    * @param format media format with optional feature directives.
    * @return whether the codec capabilities support the given format
    *         and feature requests.
    */
    bool isFormatSupported(const sp<AMessage> &format) const;

    /**
     * If the CodecCapabilities contains an AudioCapabilities.
     *
     * Not a public API to users.
     */
    bool isAudio() const;

    /**
     * If the CodecCapabilities contains a VideoCapabilities.
     *
     * Not a public API to users.
     */
    bool isVideo() const;

    /**
     * If the CodecCapabilities contains an EncoderCapabilities.
     *
     * Not a public API to users.
     */
    bool isEncoder() const;

private:
    std::string mMediaType;
    std::vector<ProfileLevel> mProfileLevels;
    std::vector<uint32_t> mColorFormats;
    int32_t mMaxSupportedInstances;

    sp<AMessage> mDefaultFormat;
    sp<AMessage> mCapabilitiesInfo;

    // Features
    std::set<std::string> mFeaturesSupported;
    std::set<std::string> mFeaturesRequired;

    std::shared_ptr<AudioCapabilities> mAudioCaps;
    std::shared_ptr<VideoCapabilities> mVideoCaps;
    std::shared_ptr<EncoderCapabilities> mEncoderCaps;

    bool supportsProfileLevel(int32_t profile, int32_t level) const;
    std::vector<Feature> getValidFeatures() const;
    int32_t getErrors() const;
};

}  // namespace android
+5 −0

File changed.

Preview size limit exceeded, changes collapsed.