| /*-------------------------------------------------------------------------- |
| 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; |
| } |