Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2017, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 --------------------------------------------------------------------------*/
     29 
     30 #define LOG_TAG "OMX-VENDOR-EXT"
     31 #include <utils/Log.h>
     32 #include "vidc_debug.h"
     33 
     34 #include "OMX_Core.h"
     35 #include "OMX_QCOMExtns.h"
     36 #include "OMX_VideoExt.h"
     37 #include "OMX_IndexExt.h"
     38 #include "vidc_vendor_extensions.h"
     39 
     40 VendorExtension::VendorExtension(OMX_INDEXTYPE id, const char *name, OMX_DIRTYPE dir,
     41         const ParamListBuilder& p)
     42     : mId(id),
     43       mName(name),
     44       mPortDir(dir),
     45       mParams(std::move(p.mParams)),
     46       mIsSet(false) {
     47 }
     48 
     49 // copy extension Info to OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE* struct passed
     50 OMX_ERRORTYPE VendorExtension::copyInfoTo(
     51         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const {
     52 
     53     // Extension info
     54     strncpy((char *)ext->cName, mName.c_str(), OMX_MAX_STRINGNAME_SIZE);
     55     ext->eDir = mPortDir;
     56     ext->nParamCount = paramCount();
     57 
     58     // Per-parameter info
     59     // Must be copied only if there are enough params to fill-in
     60     if (ext->nParamSizeUsed < ext->nParamCount) {
     61         return OMX_ErrorNone;
     62     }
     63 
     64     int i = 0;
     65     for (const Param& p : mParams) {
     66         strncpy((char *)ext->nParam[i].cKey, p.name(), OMX_MAX_STRINGNAME_SIZE);
     67         ext->nParam[i].bSet = mIsSet ? OMX_TRUE : OMX_FALSE;
     68         ext->nParam[i].eValueType = p.type();
     69         ++i;
     70     }
     71     return OMX_ErrorNone;
     72 }
     73 
     74 bool VendorExtension::setParamInt32(
     75         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
     76         OMX_S32 setInt32) const {
     77     int paramIndex = indexOfParam(paramKey);
     78     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt32)) {
     79         return false;
     80     }
     81     ext->nParam[paramIndex].nInt32 = setInt32;
     82     return true;
     83 }
     84 
     85 bool VendorExtension::setParamInt64(
     86         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
     87         OMX_S32 setInt64) const {
     88     int paramIndex = indexOfParam(paramKey);
     89     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt64)) {
     90         return false;
     91     }
     92     ext->nParam[paramIndex].nInt64 = setInt64;
     93     return true;
     94 }
     95 
     96 bool VendorExtension::setParamString(
     97         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
     98         const char *setStr) const {
     99     int paramIndex = indexOfParam(paramKey);
    100     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueString)) {
    101         return false;
    102     }
    103     strncpy((char *)ext->nParam[paramIndex].cString, setStr, OMX_MAX_STRINGVALUE_SIZE);
    104     return true;
    105 }
    106 
    107 bool VendorExtension::readParamInt32(
    108         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
    109         OMX_S32 *readInt32) const {
    110     int paramIndex = indexOfParam(paramKey);
    111     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt32)) {
    112         return false;
    113     }
    114     if (ext->nParam[paramIndex].bSet == OMX_TRUE) {
    115         *readInt32 = ext->nParam[paramIndex].nInt32;
    116         return true;
    117     }
    118     return false;
    119 }
    120 
    121 bool VendorExtension::readParamInt64(
    122         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
    123         OMX_S32 *readInt64) const {
    124     int paramIndex = indexOfParam(paramKey);
    125     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt64)) {
    126         return false;
    127     }
    128     if (ext->nParam[paramIndex].bSet == OMX_TRUE) {
    129         *readInt64 = ext->nParam[paramIndex].nInt64;
    130         return true;
    131     }
    132     return false;
    133 }
    134 
    135 bool VendorExtension::readParamInt64(
    136             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey,
    137             char *readStr) const {
    138     int paramIndex = indexOfParam(paramKey);
    139     if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueString)) {
    140         return false;
    141     }
    142     if (ext->nParam[paramIndex].bSet == OMX_TRUE) {
    143         strncpy(readStr,
    144                 (const char *)ext->nParam[paramIndex].cString, OMX_MAX_STRINGVALUE_SIZE);
    145         return true;
    146     }
    147     return false;
    148 }
    149 
    150 // Checkers
    151 OMX_ERRORTYPE VendorExtension::isConfigValid(
    152     OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const {
    153     ALOGI("isConfigValid");
    154 
    155     if (ext->nParamSizeUsed < ext->nParamCount) {
    156         DEBUG_PRINT_ERROR("allotted params(%u) < required(%u) for %s",
    157                 ext->nParamSizeUsed, ext->nParamCount, mName.c_str());
    158         return OMX_ErrorBadParameter;
    159     }
    160     if (ext->nParamCount != paramCount()) {
    161         DEBUG_PRINT_ERROR("incorrect param count(%u) v/s required(%u) for %s",
    162                 ext->nParamCount, paramCount(), mName.c_str());
    163         return OMX_ErrorBadParameter;
    164     }
    165     if (strncmp((char *)ext->cName, mName.c_str(), OMX_MAX_STRINGNAME_SIZE) != 0) {
    166         DEBUG_PRINT_ERROR("extension name mismatch(%s) v/s expected(%s)",
    167                 (char *)ext->cName, mName.c_str());
    168         return OMX_ErrorBadParameter;
    169     }
    170 
    171     for (OMX_U32 i = 0; i < paramCount(); ++i) {
    172         if (!_isParamAccessOK(ext, i)) {
    173             ALOGI("_isParamAccessOK failed for %u", i);
    174             return OMX_ErrorBadParameter;
    175         }
    176     }
    177 
    178     return OMX_ErrorNone;
    179 }
    180 
    181 //static
    182 const char* VendorExtension::typeString(OMX_ANDROID_VENDOR_VALUETYPE type) {
    183     switch (type) {
    184         case OMX_AndroidVendorValueInt32: return "Int32";
    185         case OMX_AndroidVendorValueInt64: return "Int64";
    186         case OMX_AndroidVendorValueString: return "String";
    187         default: return "InvalidType";
    188     }
    189 }
    190 
    191 std::string VendorExtension::debugString() const {
    192     std::string str = "vendor." + mName + "{";
    193     for (const Param& p : mParams) {
    194         str += "{ ";
    195         str += p.name();
    196         str += " : ";
    197         str += typeString(p.type());
    198         str += " },  ";
    199     }
    200     str += "}";
    201     return str;
    202 }
    203 
    204 bool VendorExtension::_isParamAccessTypeOK(
    205         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex,
    206         OMX_ANDROID_VENDOR_VALUETYPE type) const {
    207     if (paramIndex < 0
    208             || paramIndex >= (int)ext->nParamSizeUsed
    209             || paramIndex >= (int)paramCount()) {
    210         DEBUG_PRINT_ERROR("Invalid Param index(%d) for %s (max=%u)",
    211                 paramIndex, mName.c_str(), paramCount());
    212         return false;
    213     }
    214     if (type != mParams[paramIndex].type()) {
    215         DEBUG_PRINT_ERROR("Invalid Type for field(%s) for %s.%s (expected=%s)",
    216                 typeString(type), mName.c_str(), mParams[paramIndex].name(),
    217                 typeString(mParams[paramIndex].type()));
    218         return false;
    219     }
    220     return true;
    221 }
    222 
    223 bool VendorExtension::_isParamAccessOK(
    224         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex) const {
    225     if (paramIndex < 0
    226             || paramIndex >= (int)ext->nParamSizeUsed
    227             || paramIndex >= (int)paramCount()) {
    228         DEBUG_PRINT_ERROR("Invalid Param index(%d) for %s (max=%u)",
    229                 paramIndex, mName.c_str(), paramCount());
    230         return false;
    231     }
    232     if (ext->nParam[paramIndex].eValueType != mParams[paramIndex].type()) {
    233         DEBUG_PRINT_ERROR("Invalid Type for field(%s) for %s.%s (expected=%s)",
    234                 typeString(ext->nParam[paramIndex].eValueType),
    235                 mName.c_str(), mParams[paramIndex].name(),
    236                 typeString(mParams[paramIndex].type()));
    237         return false;
    238     }
    239     if (strncmp((const char *)ext->nParam[paramIndex].cKey,
    240             mParams[paramIndex].name(), OMX_MAX_STRINGNAME_SIZE) != 0) {
    241         DEBUG_PRINT_ERROR("Invalid Key for field(%s) for %s.%s (expected=%s)",
    242                 ext->nParam[paramIndex].cKey,
    243                 mName.c_str(), mParams[paramIndex].name(),
    244                 mParams[paramIndex].name());
    245         return false;
    246     }
    247     return true;
    248 }
    249 
    250 int VendorExtension::indexOfParam(const char *key) const {
    251     int i = 0;
    252     for (const Param& p : mParams) {
    253         if (!strncmp(key, p.name(), OMX_MAX_STRINGNAME_SIZE)) {
    254             return i;
    255         }
    256         ++i;
    257     }
    258     DEBUG_PRINT_ERROR("Failed to lookup param(%s) in extension(%s)",
    259             key, mName.c_str());
    260     return -1;
    261 }
    262 
    263 void VendorExtensionStore::dumpExtensions(const char *prefix) const {
    264     DEBUG_PRINT_HIGH("%s : Vendor extensions supported (%u)", prefix, size());
    265     for (const VendorExtension& v : mExt) {
    266         DEBUG_PRINT_HIGH("   %s", v.debugString().c_str());
    267     }
    268 }
    269