diff options
author | Thierry Strudel <tstrudel@google.com> | 2017-04-06 11:18:17 -0700 |
---|---|---|
committer | Thierry Strudel <tstrudel@google.com> | 2017-04-06 15:49:54 -0700 |
commit | aec695787aa19f0f77459fe206562c7f98d9c7ce (patch) | |
tree | e6e4f659db20cf4f0aa6dbee5cbc4e1f40df0b08 /msm8998/mm-video-v4l2 | |
parent | bbeeb076aa51549ff685b62be587400d730cb4af (diff) | |
download | media-aec695787aa19f0f77459fe206562c7f98d9c7ce.tar.gz |
msm8998: Update to 07.00.00.279.069
msm8998: from hardware/qcom/media
bb24b8c3 Merge "mm-video-v4l2: venc: Update output resolution correctly for rotation"
5a3ccc5f Merge "mm-video-v4l2: vdec: Add Vendor extensions support in decoder component"
2458dc9d Merge "mm-video-v4l2: venc: remove stale entries in m_opq_pmem_q"
2d192e02 mm-video-v4l2: venc: remove stale entries in m_opq_pmem_q
50d88a14 mm-video-v4l2: venc: Update output resolution correctly for rotation
3b698b20 mm-video-v4l2: vdec: Add Vendor extensions support in decoder component
75b571e7 mm-video-v4l2: venc: add extension to support av-timer timestamps
a017ca7c mm-video-v4l2: venc: Implement android vendor extensions
2ff90923 media: Move Video HAL libraries to vendor image
1b004d17 Merge "Intial bring up for sdm660"
fe061841 Merge "media: Move Video HAL libraries to vendor image"
4e2f76cb media: Move Video HAL libraries to vendor image
20f5a0be mm-core: Add entries for AMR encoder and decoder
ff63b1db Intial bring up for sdm660
Bug: 37062945
Signed-off-by: Thierry Strudel <tstrudel@google.com>
Change-Id: Ib77530d4e14dc157025b71af4bf61e47fff3acac
Diffstat (limited to 'msm8998/mm-video-v4l2')
15 files changed, 1070 insertions, 96 deletions
diff --git a/msm8998/mm-video-v4l2/vidc/common/Android.mk b/msm8998/mm-video-v4l2/vidc/common/Android.mk index 22d838f..fe7b875 100644 --- a/msm8998/mm-video-v4l2/vidc/common/Android.mk +++ b/msm8998/mm-video-v4l2/vidc/common/Android.mk @@ -39,6 +39,7 @@ LOCAL_SHARED_LIBRARIES := liblog libutils libcutils libdl LOCAL_SRC_FILES := src/extra_data_handler.cpp LOCAL_SRC_FILES += src/vidc_color_converter.cpp +LOCAL_SRC_FILES += src/vidc_vendor_extensions.cpp ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true) LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr diff --git a/msm8998/mm-video-v4l2/vidc/common/inc/vidc_debug.h b/msm8998/mm-video-v4l2/vidc/common/inc/vidc_debug.h index 3423a35..5f1fbca 100644 --- a/msm8998/mm-video-v4l2/vidc/common/inc/vidc_debug.h +++ b/msm8998/mm-video-v4l2/vidc/common/inc/vidc_debug.h @@ -83,6 +83,28 @@ extern int debug_level; } \ } \ +/* + * Validate OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE type param + * *assumes* VALIDATE_OMX_PARAM_DATA checks have passed + * Checks for nParamCount cannot be generalized here. it is imperative that + * the calling code handles it. + */ +#define VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext) \ + { \ + if (ext->nParamSizeUsed < 1 || ext->nParamSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { \ + ALOGE("VendorExtension: sub-params(%u) not in expected range(%u - %u)", \ + ext->nParamSizeUsed, 1, OMX_MAX_ANDROID_VENDOR_PARAMCOUNT); \ + return OMX_ErrorBadParameter; \ + } \ + OMX_U32 expectedSize = (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) + \ + ((ext->nParamSizeUsed - 1) * (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE));\ + if (ext->nSize < expectedSize) { \ + ALOGE("VendorExtension: Insifficient size(%u) v/s expected(%u)", \ + ext->nSize, expectedSize); \ + return OMX_ErrorBadParameter; \ + } \ + } \ + class auto_lock { public: auto_lock(pthread_mutex_t &lock) diff --git a/msm8998/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h b/msm8998/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h new file mode 100644 index 0000000..6763d16 --- /dev/null +++ b/msm8998/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h @@ -0,0 +1,229 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#ifndef _VIDC_VENDOR_ENXTENSIONS_H_ +#define _VIDC_VENDOR_ENXTENSIONS_H_ + +#include <inttypes.h> +#include <string.h> +#include <string> +#include <vector> + +/* + * This class represents a Vendor-Extension (except for the data). + * A Vendor extension is identified by a unique extension-name and + * is mapped to a specific OMX-extension. it contains params that + * signify individual parameter-field + * VendorExtension::mName => similar to OMX extension string. + * (Name must be unique) + * VendorExtension::mId => similar to OMX extension ID + * VendorExtension::mParam[0,1..] => similar to an individual field + * in OMX extension struct + * VendorExtension::mIsSet => flag that indicates whether this + * extension was set by the client. + * This also provides utility methods to: + * - copy info(keys/types..) to client's extension strcuture + * including copying of param-key and type of each param + * - copy data from/to the client's extension structure, given the + * param-key (this is type-aware copy) + * - sanity checks + * + * Extension name - naming convention + * - name must be unique + * - must be prefixed with "ext-" followed by component-type + * Eg: "enc" "dec" "vpp" + * - SHOULD NOT contain "." + * - keywords SHOULD be separated by "-" + * - name may contain feature-name and/or parameter-name + * Eg: "ext-enc-preprocess-rotate" + * "ext-dec-picture-order" + * + * Overall paramter-key => vendor (dot) extension-name (dot) param-key +*/ +struct VendorExtension { + + /* + * Param represents an individual parameter (field) of a VendorExtension. + * This is a variant holding values of type [int32, int64 or String]. + * Each Param has a name (unique within the extension) that is appended + * to the 'extension-name' and prefixed with "vendor." to generate the + * key that will be exposed to the client. + * + * Param name(key) - naming convention + * - key must be unique (within the extension) + * - SHOULD not contain "." + * - Keywords seperated by "-" ONLY if required + * Eg: "angle" + * "n-idr-period" + * + */ + struct Param { + Param (const std::string &name, OMX_ANDROID_VENDOR_VALUETYPE type) + : mName(name), mType(type) {} + + const char *name() const { + return mName.c_str(); + } + OMX_ANDROID_VENDOR_VALUETYPE type() const { + return mType; + } + private: + std::string mName; + OMX_ANDROID_VENDOR_VALUETYPE mType; + }; + + // helper to build a list of variable number or params + struct ParamListBuilder { + ParamListBuilder (std::initializer_list<Param> l) + : mParams(l) {} + private: + friend struct VendorExtension; + std::vector<Param> mParams; + }; + + VendorExtension(OMX_INDEXTYPE id, const char *name, OMX_DIRTYPE dir, + const ParamListBuilder& p); + + // getters + OMX_INDEXTYPE extensionIndex() const { + return (OMX_INDEXTYPE)mId; + } + const char *name() const { + return mName.c_str(); + } + OMX_U32 paramCount() const { + return (OMX_U32)mParams.size(); + } + bool isSet() const { + return mIsSet; + } + + // (the only) setter + void set() const { + mIsSet = true; + } + + // copy extension Info to OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE* struct passed (except data) + OMX_ERRORTYPE copyInfoTo(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const; + + // Type-aware data copy methods + // (NOTE: data here is passed explicitly to avoid this class having to know all types) + // returns true if value was written + bool setParamInt32(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 setInt32) const; + bool setParamInt64(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 setInt64) const; + bool setParamString(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + const char *setStr) const; + + // read-values are updated ONLY IF the param[paramIndex] is set by client + // returns true if value was read + bool readParamInt32(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 *readInt32) const; + bool readParamInt64(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 *readInt64) const; + bool readParamInt64(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + char *readStr) const; + + // Sanity checkers + // Check if the extension-name, port-dir, allotted params match + // for each param, check if key and type both match + // Must be called to check whether config data provided with setConfig is valid + OMX_ERRORTYPE isConfigValid(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const; + + // utils + static const char* typeString(OMX_ANDROID_VENDOR_VALUETYPE type); + std::string debugString() const; + +private: + // Id assigned to the extension + OMX_INDEXTYPE mId; + // Name of the extension + std::string mName; + // Port that this setting applies to + OMX_DIRTYPE mPortDir; + // parameters required for this extension + std::vector<Param> mParams; + // Flag that indicates client has set this extension. + mutable bool mIsSet; + + // check if the index is valid, name matches, type matches and is set + // This must be called to verify config-data passed with setConfig() + bool _isParamAccessOK( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex) const; + + // check if the index is valid, check against explicit type + bool _isParamAccessTypeOK( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex, + OMX_ANDROID_VENDOR_VALUETYPE type) const; + + int indexOfParam(const char *key) const; +}; + +/* + * Store(List) of all vendor extensions *that are supported* by a component. + * The list is populated (per-component) at init, based on the capabilities. + * The store is immutable once created, except for setting the flag to indicate + * -whether the extension was set by the Client + */ +struct VendorExtensionStore { + VendorExtensionStore() + : mInvalid(VendorExtension((OMX_INDEXTYPE)-1, "invalid", OMX_DirMax, {{}})) { + } + + VendorExtensionStore(const VendorExtensionStore&) = delete; + VendorExtensionStore& operator= (const VendorExtensionStore&) = delete; + + void add(const VendorExtension& _e) { + mExt.push_back(_e); + } + const VendorExtension& operator[] (OMX_U32 index) const { + return index < mExt.size() ? mExt[index] : mInvalid; + } + OMX_U32 size() const { + return mExt.size(); + } + void dumpExtensions(const char *prefix) const; + +private: + std::vector<VendorExtension> mExt; + VendorExtension mInvalid; +}; + +// Macros to help add extensions +#define ADD_EXTENSION(_name, _extIndex, _dir) \ + store.add(VendorExtension((OMX_INDEXTYPE)_extIndex, _name, _dir, { \ + +#define ADD_PARAM(_key, _type) \ + {_key, _type}, + +#define ADD_PARAM_END(_key, _type) \ + {_key, _type} })); + +#endif // _VIDC_VENDOR_ENXTENSIONS_H_ diff --git a/msm8998/mm-video-v4l2/vidc/common/src/vidc_vendor_extensions.cpp b/msm8998/mm-video-v4l2/vidc/common/src/vidc_vendor_extensions.cpp new file mode 100644 index 0000000..bc69b1f --- /dev/null +++ b/msm8998/mm-video-v4l2/vidc/common/src/vidc_vendor_extensions.cpp @@ -0,0 +1,268 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#define LOG_TAG "OMX-VENDOR-EXT" +#include <utils/Log.h> +#include "vidc_debug.h" + +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "OMX_VideoExt.h" +#include "OMX_IndexExt.h" +#include "vidc_vendor_extensions.h" + +VendorExtension::VendorExtension(OMX_INDEXTYPE id, const char *name, OMX_DIRTYPE dir, + const ParamListBuilder& p) + : mId(id), + mName(name), + mPortDir(dir), + mParams(std::move(p.mParams)), + mIsSet(false) { +} + +// copy extension Info to OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE* struct passed +OMX_ERRORTYPE VendorExtension::copyInfoTo( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const { + + // Extension info + strncpy((char *)ext->cName, mName.c_str(), OMX_MAX_STRINGNAME_SIZE); + ext->eDir = mPortDir; + ext->nParamCount = paramCount(); + + // Per-parameter info + // Must be copied only if there are enough params to fill-in + if (ext->nParamSizeUsed < ext->nParamCount) { + return OMX_ErrorNone; + } + + int i = 0; + for (const Param& p : mParams) { + strncpy((char *)ext->nParam[i].cKey, p.name(), OMX_MAX_STRINGNAME_SIZE); + ext->nParam[i].bSet = mIsSet ? OMX_TRUE : OMX_FALSE; + ext->nParam[i].eValueType = p.type(); + ++i; + } + return OMX_ErrorNone; +} + +bool VendorExtension::setParamInt32( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 setInt32) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt32)) { + return false; + } + ext->nParam[paramIndex].nInt32 = setInt32; + return true; +} + +bool VendorExtension::setParamInt64( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 setInt64) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt64)) { + return false; + } + ext->nParam[paramIndex].nInt64 = setInt64; + return true; +} + +bool VendorExtension::setParamString( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + const char *setStr) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueString)) { + return false; + } + strncpy((char *)ext->nParam[paramIndex].cString, setStr, OMX_MAX_STRINGVALUE_SIZE); + return true; +} + +bool VendorExtension::readParamInt32( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 *readInt32) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt32)) { + return false; + } + if (ext->nParam[paramIndex].bSet == OMX_TRUE) { + *readInt32 = ext->nParam[paramIndex].nInt32; + return true; + } + return false; +} + +bool VendorExtension::readParamInt64( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + OMX_S32 *readInt64) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueInt64)) { + return false; + } + if (ext->nParam[paramIndex].bSet == OMX_TRUE) { + *readInt64 = ext->nParam[paramIndex].nInt64; + return true; + } + return false; +} + +bool VendorExtension::readParamInt64( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, const char *paramKey, + char *readStr) const { + int paramIndex = indexOfParam(paramKey); + if (!_isParamAccessTypeOK(ext, paramIndex, OMX_AndroidVendorValueString)) { + return false; + } + if (ext->nParam[paramIndex].bSet == OMX_TRUE) { + strncpy(readStr, + (const char *)ext->nParam[paramIndex].cString, OMX_MAX_STRINGVALUE_SIZE); + return true; + } + return false; +} + +// Checkers +OMX_ERRORTYPE VendorExtension::isConfigValid( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) const { + ALOGI("isConfigValid"); + + if (ext->nParamSizeUsed < ext->nParamCount) { + DEBUG_PRINT_ERROR("allotted params(%u) < required(%u) for %s", + ext->nParamSizeUsed, ext->nParamCount, mName.c_str()); + return OMX_ErrorBadParameter; + } + if (ext->nParamCount != paramCount()) { + DEBUG_PRINT_ERROR("incorrect param count(%u) v/s required(%u) for %s", + ext->nParamCount, paramCount(), mName.c_str()); + return OMX_ErrorBadParameter; + } + if (strncmp((char *)ext->cName, mName.c_str(), OMX_MAX_STRINGNAME_SIZE) != 0) { + DEBUG_PRINT_ERROR("extension name mismatch(%s) v/s expected(%s)", + (char *)ext->cName, mName.c_str()); + return OMX_ErrorBadParameter; + } + + for (OMX_U32 i = 0; i < paramCount(); ++i) { + if (!_isParamAccessOK(ext, i)) { + ALOGI("_isParamAccessOK failed for %u", i); + return OMX_ErrorBadParameter; + } + } + + return OMX_ErrorNone; +} + +//static +const char* VendorExtension::typeString(OMX_ANDROID_VENDOR_VALUETYPE type) { + switch (type) { + case OMX_AndroidVendorValueInt32: return "Int32"; + case OMX_AndroidVendorValueInt64: return "Int64"; + case OMX_AndroidVendorValueString: return "String"; + default: return "InvalidType"; + } +} + +std::string VendorExtension::debugString() const { + std::string str = "vendor." + mName + "{"; + for (const Param& p : mParams) { + str += "{ "; + str += p.name(); + str += " : "; + str += typeString(p.type()); + str += " }, "; + } + str += "}"; + return str; +} + +bool VendorExtension::_isParamAccessTypeOK( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex, + OMX_ANDROID_VENDOR_VALUETYPE type) const { + if (paramIndex < 0 + || paramIndex >= (int)ext->nParamSizeUsed + || paramIndex >= (int)paramCount()) { + DEBUG_PRINT_ERROR("Invalid Param index(%d) for %s (max=%u)", + paramIndex, mName.c_str(), paramCount()); + return false; + } + if (type != mParams[paramIndex].type()) { + DEBUG_PRINT_ERROR("Invalid Type for field(%s) for %s.%s (expected=%s)", + typeString(type), mName.c_str(), mParams[paramIndex].name(), + typeString(mParams[paramIndex].type())); + return false; + } + return true; +} + +bool VendorExtension::_isParamAccessOK( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext, int paramIndex) const { + if (paramIndex < 0 + || paramIndex >= (int)ext->nParamSizeUsed + || paramIndex >= (int)paramCount()) { + DEBUG_PRINT_ERROR("Invalid Param index(%d) for %s (max=%u)", + paramIndex, mName.c_str(), paramCount()); + return false; + } + if (ext->nParam[paramIndex].eValueType != mParams[paramIndex].type()) { + DEBUG_PRINT_ERROR("Invalid Type for field(%s) for %s.%s (expected=%s)", + typeString(ext->nParam[paramIndex].eValueType), + mName.c_str(), mParams[paramIndex].name(), + typeString(mParams[paramIndex].type())); + return false; + } + if (strncmp((const char *)ext->nParam[paramIndex].cKey, + mParams[paramIndex].name(), OMX_MAX_STRINGNAME_SIZE) != 0) { + DEBUG_PRINT_ERROR("Invalid Key for field(%s) for %s.%s (expected=%s)", + ext->nParam[paramIndex].cKey, + mName.c_str(), mParams[paramIndex].name(), + mParams[paramIndex].name()); + return false; + } + return true; +} + +int VendorExtension::indexOfParam(const char *key) const { + int i = 0; + for (const Param& p : mParams) { + if (!strncmp(key, p.name(), OMX_MAX_STRINGNAME_SIZE)) { + return i; + } + ++i; + } + DEBUG_PRINT_ERROR("Failed to lookup param(%s) in extension(%s)", + key, mName.c_str()); + return -1; +} + +void VendorExtensionStore::dumpExtensions(const char *prefix) const { + DEBUG_PRINT_HIGH("%s : Vendor extensions supported (%u)", prefix, size()); + for (const VendorExtension& v : mExt) { + DEBUG_PRINT_HIGH(" %s", v.debugString().c_str()); + } +} diff --git a/msm8998/mm-video-v4l2/vidc/vdec/Android.mk b/msm8998/mm-video-v4l2/vidc/vdec/Android.mk index f2aa5db..83cddef 100644 --- a/msm8998/mm-video-v4l2/vidc/vdec/Android.mk +++ b/msm8998/mm-video-v4l2/vidc/vdec/Android.mk @@ -112,12 +112,14 @@ include $(CLEAR_VARS) LOCAL_MODULE := libOmxVdec LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 LOCAL_CFLAGS := $(libmm-vdec-def) -Werror LOCAL_C_INCLUDES += $(libmm-vdec-inc) LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-vdec-add-dep) LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl libqdutils +LOCAL_SHARED_LIBRARIES := liblog libutils libcutils libdl libqdutils LOCAL_SHARED_LIBRARIES += libqdMetaData @@ -143,6 +145,8 @@ ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_NEED_SW_VDEC)),true) LOCAL_MODULE := libOmxSwVdec LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 LOCAL_CFLAGS := $(libmm-vdec-def) LOCAL_C_INCLUDES += $(libmm-vdec-inc) LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-vdec-add-dep) diff --git a/msm8998/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msm8998/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 6b827c9..8faf1d0 100644 --- a/msm8998/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/msm8998/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -67,7 +67,6 @@ static ptrdiff_t x; //#include <binder/MemoryHeapIon.h> //#else #endif -#include <binder/MemoryHeapBase.h> #include <ui/ANativeObjectBase.h> extern "C" { #include <utils/Log.h> @@ -108,6 +107,7 @@ extern "C" { #include "ts_parser.h" #include "vidc_color_converter.h" #include "vidc_debug.h" +#include "vidc_vendor_extensions.h" #ifdef _ANDROID_ #include <cutils/properties.h> #else @@ -117,32 +117,14 @@ extern "C" { OMX_API void * get_omx_component_factory_fn(void); } -#ifdef _ANDROID_ -using namespace android; -#ifdef USE_ION -class VideoHeap : public MemoryHeapBase -{ - public: - VideoHeap(int devicefd, size_t size, void* base,ion_user_handle_t handle,int mapfd); - virtual ~VideoHeap() {} - private: - int m_ion_device_fd; - ion_user_handle_t m_ion_handle; -}; -#else -// local pmem heap object -class VideoHeap : public MemoryHeapBase -{ - public: - VideoHeap(int fd, size_t size, void* base); - virtual ~VideoHeap() {} -}; -#endif -#endif // _ANDROID_ ////////////////////////////////////////////////////////////////////////////// // Module specific globals ////////////////////////////////////////////////////////////////////////////// #define OMX_SPEC_VERSION 0x00000101 +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset((_s_), 0x0, sizeof(_name_)); \ +(_s_)->nSize = sizeof(_name_); \ +(_s_)->nVersion.nVersion = OMX_SPEC_VERSION \ ////////////////////////////////////////////////////////////////////////////// @@ -910,14 +892,6 @@ class omx_vdec: public qc_omx_component // encapsulate the waiting states. uint64_t m_flags; -#ifdef _ANDROID_ - // Heap pointer to frame buffers - struct vidc_heap { - sp<MemoryHeapBase> video_heap_ptr; - }; - struct vidc_heap *m_heap_ptr; - unsigned int m_heap_count; -#endif //_ANDROID_ // store I/P PORT state OMX_BOOL m_inp_bEnabled; // store O/P PORT state @@ -1051,6 +1025,7 @@ class omx_vdec: public qc_omx_component OMX_U32 m_reconfig_width; OMX_U32 m_reconfig_height; bool m_smoothstreaming_mode; + bool m_decode_order_mode; bool m_input_pass_buffer_fd; DescribeColorAspectsParams m_client_color_space; @@ -1128,11 +1103,6 @@ class omx_vdec: public qc_omx_component #endif unsigned char *pmem_baseaddress[MAX_COUNT]; int pmem_fd[MAX_COUNT]; - struct vidc_heap { - sp<MemoryHeapBase> video_heap_ptr; - }; - struct vidc_heap m_heap_ptr[MAX_COUNT]; - OMX_ERRORTYPE cache_ops(unsigned int index, unsigned int cmd); inline OMX_ERRORTYPE cache_clean_buffer(unsigned int index) { return cache_ops(index, ION_IOC_CLEAN_CACHES); @@ -1304,6 +1274,16 @@ class omx_vdec: public qc_omx_component } }; client_extradata_info m_client_extradata_info; + + OMX_ERRORTYPE get_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext); + OMX_ERRORTYPE set_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext); + + void init_vendor_extensions (VendorExtensionStore&); + + // list of extensions is not mutable after initialization + const VendorExtensionStore mVendorExtensionStore; }; #ifdef _MSM8974_ diff --git a/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp b/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp new file mode 100644 index 0000000..ac6d629 --- /dev/null +++ b/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp @@ -0,0 +1,128 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +void omx_vdec::init_vendor_extensions (VendorExtensionStore &store) { + + //TODO: add extensions based on Codec, m_platform and/or other capability queries + + ADD_EXTENSION("qti-ext-dec-picture-order", OMX_QcomIndexParamVideoDecoderPictureOrder, OMX_DirOutput) + ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32) +} + + +OMX_ERRORTYPE omx_vdec::get_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { + if (ext->nIndex >= mVendorExtensionStore.size()) { + return OMX_ErrorNoMore; + } + + const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; + DEBUG_PRINT_LOW("VendorExt: getConfig: index=%u (%s)", ext->nIndex, vExt.name()); + + vExt.copyInfoTo(ext); + if (ext->nParamSizeUsed < vExt.paramCount()) { + // this happens during initial getConfig to query only extension-name and param-count + return OMX_ErrorNone; + } + + // We now have sufficient params allocated in extension data passed. + // Following code is to set the extension-specific data + + bool setStatus = true; + + switch ((OMX_U32)vExt.extensionIndex()) { + case OMX_QcomIndexParamVideoDecoderPictureOrder: + { + setStatus &= vExt.setParamInt32(ext, "enable", m_decode_order_mode); + break; + } + default: + { + return OMX_ErrorNotImplemented; + } + } + return setStatus ? OMX_ErrorNone : OMX_ErrorUndefined; +} + +OMX_ERRORTYPE omx_vdec::set_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { + + ALOGI("set_vendor_extension_config"); + if (ext->nIndex >= mVendorExtensionStore.size()) { + DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", + ext->nIndex, mVendorExtensionStore.size()); + return OMX_ErrorBadParameter; + } + + const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; + DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); + + OMX_ERRORTYPE err = OMX_ErrorNone; + err = vExt.isConfigValid(ext); + if (err != OMX_ErrorNone) { + return err; + } + + // mark this as set, regardless of set_config succeeding/failing. + // App will know by inconsistent values in output-format + vExt.set(); + + bool valueSet = false; + switch ((OMX_U32)vExt.extensionIndex()) { + case OMX_QcomIndexParamVideoDecoderPictureOrder: + { + OMX_S32 pic_order_enable = 0; + valueSet |= vExt.readParamInt32(ext, "enable", &pic_order_enable); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_QcomIndexParamVideoDecoderPictureOrder : %d", + pic_order_enable); + + QOMX_VIDEO_DECODER_PICTURE_ORDER decParam; + OMX_INIT_STRUCT(&decParam, QOMX_VIDEO_DECODER_PICTURE_ORDER); + decParam.eOutputPictureOrder = + pic_order_enable ? QOMX_VIDEO_DECODE_ORDER : QOMX_VIDEO_DISPLAY_ORDER; + + err = set_parameter( + NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder, &decParam); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexParamVideoDecoderPictureOrder failed !"); + } + break; + } + default: + { + return OMX_ErrorNotImplemented; + } + } + + return err; +} diff --git a/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp index 7081cf6..18befed 100644 --- a/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp +++ b/msm8998/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp @@ -564,27 +564,6 @@ void *get_omx_component_factory_fn(void) return (new omx_vdec); } -#ifdef _ANDROID_ -#ifdef USE_ION -VideoHeap::VideoHeap(int devicefd, size_t size, void* base, - ion_user_handle_t handle, int ionMapfd) -{ - (void) devicefd; - (void) size; - (void) base; - (void) handle; - (void) ionMapfd; - // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); -} -#else -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif -#endif // _ANDROID_ - bool is_platform_tp10capture_supported() { char platform_name[PROPERTY_VALUE_MAX] = {0}; @@ -630,9 +609,6 @@ omx_vdec::omx_vdec(): m_error_propogated(false), m_inp_bPopulated(OMX_FALSE), m_out_bPopulated(OMX_FALSE), m_flags(0), -#ifdef _ANDROID_ - m_heap_ptr(NULL), -#endif m_inp_bEnabled(OMX_TRUE), m_out_bEnabled(OMX_TRUE), m_in_alloc_cnt(0), @@ -840,6 +816,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false), m_smoothstreaming_mode = false; m_smoothstreaming_width = 0; m_smoothstreaming_height = 0; + m_decode_order_mode = false; is_q6_platform = false; m_perf_control.send_hint_to_mpctl(true); m_input_pass_buffer_fd = false; @@ -2774,6 +2751,12 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) } } + { + VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore); + init_vendor_extensions(*extStore); + mVendorExtensionStore.dumpExtensions((const char *)role); + } + if (eRet != OMX_ErrorNone) { DEBUG_PRINT_ERROR("Component Init Failed"); } else { @@ -4785,6 +4768,8 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, eRet = OMX_ErrorUnsupportedSetting; } } + m_decode_order_mode = + pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER; break; } case OMX_QcomIndexParamConcealMBMapExtraData: @@ -5448,6 +5433,15 @@ OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, break; } + case OMX_IndexConfigAndroidVendorExtension: + { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); + + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = + reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); + VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); + return get_vendor_extension_config(ext); + } default: { DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex); @@ -5690,6 +5684,15 @@ OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR"); memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams)); return ret; + + } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); + + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = + reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); + VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); + + return set_vendor_extension_config(ext); } return OMX_ErrorNotImplemented; @@ -12687,7 +12690,6 @@ OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( #ifdef USE_ION omx->free_ion_memory(&op_buf_ion_info[index]); #endif - m_heap_ptr[index].video_heap_ptr = NULL; if (allocated_count > 0) allocated_count--; else @@ -12760,11 +12762,7 @@ OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_conve omx->free_ion_memory(&op_buf_ion_info[i]); return OMX_ErrorInsufficientResources; } - m_heap_ptr[i].video_heap_ptr = new VideoHeap ( - op_buf_ion_info[i].ion_device_fd,buffer_size_req, - pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); #endif - m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get(); m_pmem_info_client[i].offset = 0; m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; @@ -13371,3 +13369,9 @@ prefetch_exit: free(custom_data); } } + + +// No code beyond this ! + +// inline import of vendor-extensions implementation +#include "omx_vdec_extensions.hpp" diff --git a/msm8998/mm-video-v4l2/vidc/venc/Android.mk b/msm8998/mm-video-v4l2/vidc/venc/Android.mk index 595daff..0047649 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/Android.mk +++ b/msm8998/mm-video-v4l2/vidc/venc/Android.mk @@ -26,7 +26,7 @@ TARGETS_THAT_NEED_SW_VENC_MPEG4 := msm8909 msm8937 TARGETS_THAT_NEED_SW_VENC_HEVC := msm8992 TARGETS_THAT_SUPPORT_UBWC := msm8996 msm8998 TARGETS_THAT_SUPPORT_VQZIP := msm8996 msm8998 -TARGETS_THAT_SUPPORT_PQ := msm8996 msm8998 sdm660 msm8953 +TARGETS_THAT_SUPPORT_PQ := msm8996 msm8998 msm8953 TARGETS_THAT_USE_NV21 := sdm660 msm8953 ifeq ($(TARGET_BOARD_PLATFORM),msm8610) @@ -109,12 +109,14 @@ include $(CLEAR_VARS) LOCAL_MODULE := libOmxVenc LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 LOCAL_CFLAGS := $(libmm-venc-def) LOCAL_C_INCLUDES := $(libmm-venc-inc) LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-venc-add-dep) LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \ +LOCAL_SHARED_LIBRARIES := liblog libutils libcutils \ libdl libgui ifeq ($(BOARD_USES_ADRENO), true) LOCAL_SHARED_LIBRARIES += libc2dcolorconvert @@ -140,12 +142,14 @@ libmm-venc-inc += $(TARGET_OUT_HEADERS)/mm-video/swvenc LOCAL_MODULE := libOmxSwVencMpeg4 LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 LOCAL_CFLAGS := $(libmm-venc-def) LOCAL_C_INCLUDES := $(libmm-venc-inc) LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-venc-add-dep) LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \ +LOCAL_SHARED_LIBRARIES := liblog libutils libcutils \ libdl libgui LOCAL_SHARED_LIBRARIES += libMpeg4SwEncoder ifeq ($(BOARD_USES_ADRENO), true) diff --git a/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h index 341fac6..8643e3f 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h +++ b/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h @@ -47,7 +47,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdio.h> #include <sys/mman.h> #ifdef _ANDROID_ -#include <binder/MemoryHeapBase.h> #ifdef _ANDROID_ICS_ #include "QComOMXMetadata.h" #endif @@ -68,17 +67,11 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <dlfcn.h> #include "C2DColorConverter.h" #include "vidc_debug.h" +#include <vector> +#include "vidc_vendor_extensions.h" #ifdef _ANDROID_ using namespace android; -// local pmem heap object -class VideoHeap : public MemoryHeapBase -{ - public: - VideoHeap(int fd, size_t size, void* base); - virtual ~VideoHeap() {} -}; - #include <utils/Log.h> #endif // _ANDROID_ @@ -585,6 +578,15 @@ class omx_video: public qc_omx_component bool is_conv_needed(int, int); void print_debug_color_aspects(ColorAspects *aspects, const char *prefix); + OMX_ERRORTYPE get_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext); + OMX_ERRORTYPE set_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext); + void init_vendor_extensions(VendorExtensionStore&); + // Extensions-store is immutable after initialization (i.e cannot add/remove/change + // extensions once added !) + const VendorExtensionStore mVendorExtensionStore; + #ifdef USE_ION int alloc_map_ion_memory(int size, struct ion_allocation_data *alloc_data, @@ -674,6 +676,7 @@ class omx_video: public qc_omx_component DescribeColorAspectsParams m_sConfigColorAspects; OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE m_sParamTemporalLayers; OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE m_sConfigTemporalLayers; + QOMX_ENABLETYPE m_sParamAVTimerTimestampMode; // use VT-timestamps in gralloc-handle // fill this buffer queue omx_cmd_queue m_ftb_q; @@ -703,10 +706,6 @@ class omx_video: public qc_omx_component uint64_t m_etb_count; uint64_t m_fbd_count; OMX_TICKS m_etb_timestamp; -#ifdef _ANDROID_ - // Heap pointer to frame buffers - sp<MemoryHeapBase> m_heap_ptr; -#endif //_ANDROID_ // to know whether Event Port Settings change has been triggered or not. bool m_event_port_settings_sent; OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; diff --git a/msm8998/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/msm8998/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h index fab7317..bf35a22 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h +++ b/msm8998/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h @@ -345,6 +345,7 @@ class venc_dev bool venc_h264_transform_8x8(OMX_BOOL enable); bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); bool venc_get_seq_hdr(void *, unsigned, unsigned *); + bool venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h); bool venc_loaded_start(void); bool venc_loaded_stop(void); bool venc_loaded_start_done(void); @@ -640,6 +641,7 @@ class venc_dev }; BatchInfo mBatchInfo; + bool mUseAVTimerTimestamps; }; enum instance_state { diff --git a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp index b4fe545..742ae4f 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp +++ b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp @@ -245,15 +245,6 @@ unsigned omx_video::omx_cmd_queue::get_q_msg_type() } - -#ifdef _ANDROID_ -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif // _ANDROID_ - /* ====================================================================== FUNCTION omx_venc::omx_venc @@ -2349,6 +2340,15 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers)); break; } + case OMX_IndexConfigAndroidVendorExtension: + { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); + + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = + reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); + VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); + return get_vendor_extension_config(ext); + } default: DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); @@ -3002,6 +3002,14 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) { auto_lock l(m_lock); + if (mUseProxyColorFormat) { + if (m_opq_pmem_q.m_size) { + unsigned long addr, p1, id; + m_opq_pmem_q.pop_entry(&addr, &p1, &id); + DEBUG_PRINT_LOW("Removed entry in m_opq_pmem_q: address %lu", addr); + } + } + if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) { DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case"); if(!secure_session) { @@ -5471,3 +5479,8 @@ OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp) { VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers); return retVal; } + +// no code beyond this ! + +// inline import of vendor extensions implementation +#include "omx_video_extensions.hpp" diff --git a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp index b42c288..23cfb0a 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp +++ b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp @@ -574,6 +574,9 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) OMX_INIT_STRUCT(&m_sConfigTemporalLayers, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE); + OMX_INIT_STRUCT(&m_sParamAVTimerTimestampMode, QOMX_ENABLETYPE); + m_sParamAVTimerTimestampMode.bEnable = OMX_FALSE; + m_state = OMX_StateLoaded; m_sExtraData = 0; @@ -640,6 +643,13 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) } } DEBUG_PRINT_INFO("Component_init : %s : return = 0x%x", m_nkind, eRet); + + { + VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore); + init_vendor_extensions(*extStore); + mVendorExtensionStore.dumpExtensions((const char *)m_nkind); + } + return eRet; init_error: handle->venc_close(); @@ -1779,6 +1789,17 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, } break; } + case OMX_QTIIndexParamEnableAVTimerTimestamps: + { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); + if (!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QTIIndexParamEnableAVTimerTimestamps)) { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamEnableAVTimerTimestamps failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamAVTimerTimestampMode, paramData, sizeof(QOMX_ENABLETYPE)); + break; + } case OMX_IndexParamVideoSliceFMO: default: { @@ -2035,6 +2056,15 @@ OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorUnsupportedSetting; } m_sConfigFrameRotation.nRotation = pParam->nRotation; + + // Update output-port resolution (since it might have been flipped by rotation) + if (handle->venc_get_dimensions(PORT_INDEX_OUT, + &m_sOutPortDef.format.video.nFrameWidth, + &m_sOutPortDef.format.video.nFrameHeight)) { + DEBUG_PRINT_HIGH("set Rotation: updated dimensions = %u x %u", + m_sOutPortDef.format.video.nFrameWidth, + m_sOutPortDef.format.video.nFrameHeight); + } break; } case OMX_QcomIndexConfigVideoFramePackingArrangement: @@ -2277,6 +2307,17 @@ OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorUnsupportedSetting; } } + case OMX_IndexConfigAndroidVendorExtension: + { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); + + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = + reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); + VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); + + return set_vendor_extension_config(ext); + } + default: DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); break; @@ -2355,11 +2396,6 @@ OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) m_cmd_q.m_read = m_cmd_q.m_write =0; m_etb_q.m_read = m_etb_q.m_write =0; -#ifdef _ANDROID_ - // Clear the strong reference - DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()"); - m_heap_ptr.clear(); -#endif // _ANDROID_ DEBUG_PRINT_HIGH("Calling venc_close()"); if (handle) { handle->venc_close(); diff --git a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp new file mode 100644 index 0000000..5be091e --- /dev/null +++ b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_extensions.hpp @@ -0,0 +1,241 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +void omx_video::init_vendor_extensions(VendorExtensionStore &store) { + + //TODO: add extensions based on Codec, m_platform and/or other capability queries + + ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput) + ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32) + + ADD_EXTENSION("qti-ext-enc-avc-intra-period", OMX_IndexConfigVideoAVCIntraPeriod, OMX_DirOutput) + ADD_PARAM ("n-pframes", OMX_AndroidVendorValueInt32) + ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32) + + ADD_EXTENSION("qti-ext-enc-error-correction", OMX_IndexParamVideoErrorCorrection, OMX_DirOutput) + ADD_PARAM_END("resync-marker-spacing-bits", OMX_AndroidVendorValueInt32) + + ADD_EXTENSION("qti-ext-enc-custom-profile-level", OMX_IndexParamVideoProfileLevelCurrent, OMX_DirOutput) + ADD_PARAM ("profile", OMX_AndroidVendorValueInt32) + ADD_PARAM_END("level", OMX_AndroidVendorValueInt32) + + ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps, OMX_DirInput) + ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32) +} + +OMX_ERRORTYPE omx_video::get_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { + if (ext->nIndex >= mVendorExtensionStore.size()) { + return OMX_ErrorNoMore; + } + + const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; + DEBUG_PRINT_LOW("VendorExt: getConfig: index=%u (%s)", ext->nIndex, vExt.name()); + + vExt.copyInfoTo(ext); + if (ext->nParamSizeUsed < vExt.paramCount()) { + // this happens during initial getConfig to query only extension-name and param-count + return OMX_ErrorNone; + } + + // We now have sufficient params allocated in extension data passed. + // Following code is to set the extension-specific data + + bool setStatus = true; + + switch ((OMX_U32)vExt.extensionIndex()) { + case OMX_IndexConfigCommonRotate: + { + setStatus &= vExt.setParamInt32(ext, "angle", m_sConfigFrameRotation.nRotation); + break; + } + case OMX_IndexConfigVideoAVCIntraPeriod: + { + setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sConfigAVCIDRPeriod.nPFrames); + setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sConfigAVCIDRPeriod.nIDRPeriod); + break; + } + case OMX_IndexParamVideoErrorCorrection: + { + // "bits" @0 + setStatus &= vExt.setParamInt32(ext, + "resync-marker-spacing-bits", m_sErrorCorrection.nResynchMarkerSpacing); + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + setStatus &= vExt.setParamInt32(ext, "profile", m_sParamProfileLevel.eProfile); + setStatus &= vExt.setParamInt32(ext, "level", m_sParamProfileLevel.eLevel); + + break; + } + case OMX_QTIIndexParamEnableAVTimerTimestamps: + { + setStatus &= vExt.setParamInt32(ext, "enable", m_sParamAVTimerTimestampMode.bEnable); + break; + } + default: + { + return OMX_ErrorNotImplemented; + } + } + return setStatus ? OMX_ErrorNone : OMX_ErrorUndefined; +} + +OMX_ERRORTYPE omx_video::set_vendor_extension_config( + OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { + + ALOGI("set_vendor_extension_config"); + if (ext->nIndex >= mVendorExtensionStore.size()) { + DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", + ext->nIndex, mVendorExtensionStore.size()); + return OMX_ErrorBadParameter; + } + + const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; + DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); + + OMX_ERRORTYPE err = OMX_ErrorNone; + err = vExt.isConfigValid(ext); + if (err != OMX_ErrorNone) { + return err; + } + + // mark this as set, regardless of set_config succeeding/failing. + // App will know by inconsistent values in output-format + vExt.set(); + + bool valueSet = false; + switch ((OMX_U32)vExt.extensionIndex()) { + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE rotationParam; + memcpy(&rotationParam, &m_sConfigFrameRotation, sizeof(OMX_CONFIG_ROTATIONTYPE)); + valueSet |= vExt.readParamInt32(ext, "angle", &rotationParam.nRotation); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigCommonRotate : %d", + rotationParam.nRotation); + + err = set_config( + NULL, OMX_IndexConfigCommonRotate, &rotationParam); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigCommonRotate failed !"); + } + break; + } + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD idrConfig; + memcpy(&idrConfig, &m_sConfigAVCIDRPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD)); + valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(idrConfig.nPFrames)); + valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(idrConfig.nIDRPeriod)); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d", + idrConfig.nPFrames, idrConfig.nIDRPeriod); + + err = set_config( + NULL, OMX_IndexConfigVideoAVCIntraPeriod, &idrConfig); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigVideoAVCIntraPeriod failed !"); + } + break; + } + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ecParam; + memcpy(&ecParam, &m_sErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + valueSet |= vExt.readParamInt32(ext, + "resync-marker-spacing-bits", (OMX_S32 *)&(ecParam.nResynchMarkerSpacing)); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: resync-marker-spacing : %d bits", + ecParam.nResynchMarkerSpacing); + + err = set_parameter( + NULL, OMX_IndexParamVideoErrorCorrection, &ecParam); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoErrorCorrection failed !"); + } + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE profileParam; + memcpy(&profileParam, &m_sParamProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + valueSet |= vExt.readParamInt32(ext, "profile", (OMX_S32 *)&(profileParam.eProfile)); + valueSet |= vExt.readParamInt32(ext, "level", (OMX_S32 *)&(profileParam.eLevel)); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: custom-profile/level : profile=%u level=%u", + (OMX_U32)profileParam.eProfile, (OMX_U32)profileParam.eLevel); + + err = set_parameter( + NULL, OMX_IndexParamVideoProfileLevelCurrent, &profileParam); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoProfileLevelCurrent failed !"); + } + + break; + } + case OMX_QTIIndexParamEnableAVTimerTimestamps: + { + QOMX_ENABLETYPE avTimerEnableParam; + memcpy(&avTimerEnableParam, &m_sParamAVTimerTimestampMode, sizeof(QOMX_ENABLETYPE)); + valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(avTimerEnableParam.bEnable)); + if (!valueSet) { + break; + } + + DEBUG_PRINT_HIGH("VENDOR-EXT: AV-timer timestamp mode enable=%u", avTimerEnableParam.bEnable); + + err = set_parameter( + NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamEnableAVTimerTimestamps, &avTimerEnableParam); + if (err != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamEnableAVTimerTimestamps failed !"); + } + + break; + } + default: + { + return OMX_ErrorNotImplemented; + } + } + return err; +} diff --git a/msm8998/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msm8998/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp index 1b4cd07..3dac085 100644 --- a/msm8998/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp +++ b/msm8998/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -270,6 +270,8 @@ venc_dev::venc_dev(class omx_venc *venc_class) snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); + + mUseAVTimerTimestamps = false; } venc_dev::~venc_dev() @@ -1652,6 +1654,22 @@ bool venc_dev::venc_get_seq_hdr(void *buffer, return true; } +bool venc_dev::venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h) { + struct v4l2_format fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.type = portIndex == PORT_INDEX_OUT ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) { + DEBUG_PRINT_ERROR("Failed to get format on %s port", + portIndex == PORT_INDEX_OUT ? "capture" : "output"); + return false; + } + *w = fmt.fmt.pix_mp.width; + *h = fmt.fmt.pix_mp.height; + return true; +} + bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count, OMX_U32 *actual_buff_count, OMX_U32 *buff_size, @@ -2652,6 +2670,13 @@ bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) } break; } + case OMX_QTIIndexParamEnableAVTimerTimestamps: + { + QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData; + mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE; + DEBUG_PRINT_INFO("AVTimer timestamps enabled"); + break; + } case OMX_IndexParamVideoSliceFMO: default: DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u", @@ -3963,6 +3988,15 @@ bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, return false; } + if (mUseAVTimerTimestamps) { + uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000; + if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0 + && avTimerTimestampNs > 0) { + bufhdr->nTimeStamp = avTimerTimestampNs / 1000; + DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp); + } + } + if (!streaming[OUTPUT_PORT]) { int color_space = 0; // Moment of truth... actual colorspace is known here.. @@ -6371,6 +6405,15 @@ bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle) memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + if (rotation_angle == 90 || rotation_angle == 270) { + OMX_U32 nWidth = m_sVenc_cfg.dvs_height; + OMX_U32 nHeight = m_sVenc_cfg.dvs_width; + m_sVenc_cfg.dvs_height = nHeight; + m_sVenc_cfg.dvs_width = nWidth; + DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu", + rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height); + } + fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; |