From 69829f3bd09ee4e6be49fee8795c5df24c4da70e Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 30 Mar 2012 13:02:09 -0700 Subject: Add a few more APIs to MediaCodecList. Change-Id: I5ac193cd40c82bbcd87c1e55003b78102e8d4674 --- media/libstagefright/MediaCodecList.cpp | 80 +++++++++++++++++++++++++ media/libstagefright/OMXCodec.cpp | 100 ++++++++++++++++++-------------- 2 files changed, 137 insertions(+), 43 deletions(-) (limited to 'media/libstagefright') diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index a31be0a..c39aa77 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include @@ -448,6 +450,10 @@ ssize_t MediaCodecList::findCodecByName(const char *name) const { return -ENOENT; } +size_t MediaCodecList::countCodecs() const { + return mCodecInfos.size(); +} + const char *MediaCodecList::getCodecName(size_t index) const { if (index >= mCodecInfos.size()) { return NULL; @@ -457,6 +463,15 @@ const char *MediaCodecList::getCodecName(size_t index) const { return info.mName.c_str(); } +bool MediaCodecList::isEncoder(size_t index) const { + if (index >= mCodecInfos.size()) { + return NULL; + } + + const CodecInfo &info = mCodecInfos.itemAt(index); + return info.mIsEncoder; +} + bool MediaCodecList::codecHasQuirk( size_t index, const char *quirkName) const { if (index >= mCodecInfos.size()) { @@ -475,4 +490,69 @@ bool MediaCodecList::codecHasQuirk( return false; } +status_t MediaCodecList::getSupportedTypes( + size_t index, Vector *types) const { + types->clear(); + + if (index >= mCodecInfos.size()) { + return -ERANGE; + } + + const CodecInfo &info = mCodecInfos.itemAt(index); + + for (size_t i = 0; i < mTypes.size(); ++i) { + uint32_t typeMask = 1ul << mTypes.valueAt(i); + + if (info.mTypes & typeMask) { + types->push(mTypes.keyAt(i)); + } + } + + return OK; +} + +status_t MediaCodecList::getCodecCapabilities( + size_t index, const char *type, + Vector *profileLevels, + Vector *colorFormats) const { + profileLevels->clear(); + colorFormats->clear(); + + if (index >= mCodecInfos.size()) { + return -ERANGE; + } + + const CodecInfo &info = mCodecInfos.itemAt(index); + + OMXClient client; + status_t err = client.connect(); + if (err != OK) { + return err; + } + + CodecCapabilities caps; + err = QueryCodec( + client.interface(), + info.mName.c_str(), type, info.mIsEncoder, &caps); + + if (err != OK) { + return err; + } + + for (size_t i = 0; i < caps.mProfileLevels.size(); ++i) { + const CodecProfileLevel &src = caps.mProfileLevels.itemAt(i); + + ProfileLevel profileLevel; + profileLevel.mProfile = src.mProfile; + profileLevel.mLevel = src.mLevel; + profileLevels->push(profileLevel); + } + + for (size_t i = 0; i < caps.mColorFormats.size(); ++i) { + colorFormats->push(caps.mColorFormats.itemAt(i)); + } + + return OK; +} + } // namespace android diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index e844e36..1c4b47e 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -4509,67 +4509,81 @@ status_t QueryCodecs( for (size_t c = 0; c < matchingCodecs.size(); c++) { const char *componentName = matchingCodecs.itemAt(c).string(); - if (strncmp(componentName, "OMX.", 4)) { - // Not an OpenMax component but a software codec. - - results->push(); - CodecCapabilities *caps = &results->editItemAt(results->size() - 1); - caps->mComponentName = componentName; - continue; - } + results->push(); + CodecCapabilities *caps = &results->editItemAt(results->size() - 1); - sp observer = new OMXCodecObserver; - IOMX::node_id node; - status_t err = omx->allocateNode(componentName, observer, &node); + status_t err = + QueryCodec(omx, componentName, mime, !queryDecoders, caps); if (err != OK) { - continue; + results->removeAt(results->size() - 1); } + } + + return OK; +} - OMXCodec::setComponentRole(omx, node, !queryDecoders, mime); +status_t QueryCodec( + const sp &omx, + const char *componentName, const char *mime, + bool isEncoder, + CodecCapabilities *caps) { + if (strncmp(componentName, "OMX.", 4)) { + // Not an OpenMax component but a software codec. - results->push(); - CodecCapabilities *caps = &results->editItemAt(results->size() - 1); caps->mComponentName = componentName; + return OK; + } - OMX_VIDEO_PARAM_PROFILELEVELTYPE param; - InitOMXParams(¶m); + sp observer = new OMXCodecObserver; + IOMX::node_id node; + status_t err = omx->allocateNode(componentName, observer, &node); - param.nPortIndex = queryDecoders ? 0 : 1; + if (err != OK) { + return err; + } - for (param.nProfileIndex = 0;; ++param.nProfileIndex) { - err = omx->getParameter( - node, OMX_IndexParamVideoProfileLevelQuerySupported, - ¶m, sizeof(param)); + OMXCodec::setComponentRole(omx, node, isEncoder, mime); - if (err != OK) { - break; - } + caps->mComponentName = componentName; - CodecProfileLevel profileLevel; - profileLevel.mProfile = param.eProfile; - profileLevel.mLevel = param.eLevel; + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + InitOMXParams(¶m); - caps->mProfileLevels.push(profileLevel); - } + param.nPortIndex = !isEncoder ? 0 : 1; - // Color format query - OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; - InitOMXParams(&portFormat); - portFormat.nPortIndex = queryDecoders ? 1 : 0; - for (portFormat.nIndex = 0;; ++portFormat.nIndex) { - err = omx->getParameter( - node, OMX_IndexParamVideoPortFormat, - &portFormat, sizeof(portFormat)); - if (err != OK) { - break; - } - caps->mColorFormats.push(portFormat.eColorFormat); + for (param.nProfileIndex = 0;; ++param.nProfileIndex) { + err = omx->getParameter( + node, OMX_IndexParamVideoProfileLevelQuerySupported, + ¶m, sizeof(param)); + + if (err != OK) { + break; } - CHECK_EQ(omx->freeNode(node), (status_t)OK); + CodecProfileLevel profileLevel; + profileLevel.mProfile = param.eProfile; + profileLevel.mLevel = param.eLevel; + + caps->mProfileLevels.push(profileLevel); } + // Color format query + OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; + InitOMXParams(&portFormat); + portFormat.nPortIndex = !isEncoder ? 1 : 0; + for (portFormat.nIndex = 0;; ++portFormat.nIndex) { + err = omx->getParameter( + node, OMX_IndexParamVideoPortFormat, + &portFormat, sizeof(portFormat)); + if (err != OK) { + break; + } + caps->mColorFormats.push(portFormat.eColorFormat); + } + + CHECK_EQ(omx->freeNode(node), (status_t)OK); + return OK; } -- cgit v1.1