You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1034 lines
40 KiB
1034 lines
40 KiB
/* |
|
* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
|
|
#define LOG_TAG "OMXVideoEncoderBase" |
|
#include "OMXVideoEncoderBase.h" |
|
#include "IntelMetadataBuffer.h" |
|
#include <cutils/properties.h> |
|
#include <wrs_omxil_core/log.h> |
|
#include <media/stagefright/foundation/AUtils.h> |
|
|
|
static const char *RAW_MIME_TYPE = "video/raw"; |
|
|
|
OMXVideoEncoderBase::OMXVideoEncoderBase() |
|
:mVideoEncoder(NULL) |
|
,mEncoderParams(NULL) |
|
,mFrameInputCount(0) |
|
,mFrameOutputCount(0) |
|
,mFirstFrame(OMX_TRUE) |
|
,mFrameRetrieved(OMX_TRUE) |
|
,mStoreMetaDataInBuffers(OMX_FALSE) |
|
,mSyncEncoding(OMX_TRUE) |
|
,mOmxLogLevel(0) |
|
,mBlackFramePointer(NULL) { |
|
mEncoderParams = new VideoParamsCommon(); |
|
if (!mEncoderParams) LOGE("OMX_ErrorInsufficientResources"); |
|
|
|
char logLevelProp[128]; |
|
if (property_get("omxenc.debug", logLevelProp, NULL)) { |
|
mOmxLogLevel = atoi(logLevelProp); |
|
LOGD("Debug level is %d", mOmxLogLevel); |
|
} |
|
|
|
LOGV("OMXVideoEncoderBase::OMXVideoEncoderBase end"); |
|
} |
|
|
|
OMXVideoEncoderBase::~OMXVideoEncoderBase() { |
|
|
|
// destroy ports |
|
if (this->ports) { |
|
if (this->ports[INPORT_INDEX]) { |
|
delete this->ports[INPORT_INDEX]; |
|
this->ports[INPORT_INDEX] = NULL; |
|
} |
|
|
|
if (this->ports[OUTPORT_INDEX]) { |
|
delete this->ports[OUTPORT_INDEX]; |
|
this->ports[OUTPORT_INDEX] = NULL; |
|
} |
|
} |
|
|
|
if (mBlackFramePointer) { |
|
free(mBlackFramePointer); |
|
mBlackFramePointer = NULL; |
|
} |
|
// Release video encoder object |
|
if(mVideoEncoder) { |
|
releaseVideoEncoder(mVideoEncoder); |
|
mVideoEncoder = NULL; |
|
} |
|
|
|
if(mEncoderParams) { |
|
delete mEncoderParams; |
|
mEncoderParams = NULL; |
|
} |
|
|
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) { |
|
this->ports[INPORT_INDEX] = new PortVideo; |
|
if (this->ports[INPORT_INDEX] == NULL) { |
|
return OMX_ErrorInsufficientResources; |
|
} |
|
|
|
PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); |
|
|
|
// OMX_PARAM_PORTDEFINITIONTYPE |
|
OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; |
|
memset(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput)); |
|
SetTypeHeader(¶mPortDefinitionInput, sizeof(paramPortDefinitionInput)); |
|
paramPortDefinitionInput.nPortIndex = INPORT_INDEX; |
|
paramPortDefinitionInput.eDir = OMX_DirInput; |
|
paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; |
|
paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT; |
|
paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE; |
|
paramPortDefinitionInput.bEnabled = OMX_TRUE; |
|
paramPortDefinitionInput.bPopulated = OMX_FALSE; |
|
paramPortDefinitionInput.eDomain = OMX_PortDomainVideo; |
|
paramPortDefinitionInput.format.video.cMIMEType = (OMX_STRING)RAW_MIME_TYPE; |
|
paramPortDefinitionInput.format.video.pNativeRender = NULL; |
|
paramPortDefinitionInput.format.video.nFrameWidth = 176; |
|
paramPortDefinitionInput.format.video.nFrameHeight = 144; |
|
paramPortDefinitionInput.format.video.nStride = 0; |
|
paramPortDefinitionInput.format.video.nSliceHeight = 0; |
|
paramPortDefinitionInput.format.video.nBitrate = 64000; |
|
paramPortDefinitionInput.format.video.xFramerate = 15 << 16; |
|
paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE; |
|
paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; |
|
paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; |
|
paramPortDefinitionInput.format.video.pNativeWindow = NULL; |
|
paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE; |
|
paramPortDefinitionInput.nBufferAlignment = 0; |
|
|
|
// Nothing specific to initialize input port. |
|
InitInputPortFormatSpecific(¶mPortDefinitionInput); |
|
|
|
port->SetPortDefinition(¶mPortDefinitionInput, true); |
|
|
|
// Set port buffer 4k aligned |
|
port->SetMemAlignment(4096); |
|
|
|
// OMX_VIDEO_PARAM_PORTFORMATTYPE |
|
OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; |
|
memset(¶mPortFormat, 0, sizeof(paramPortFormat)); |
|
SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); |
|
paramPortFormat.nPortIndex = INPORT_INDEX; |
|
paramPortFormat.nIndex = 0; |
|
paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat; |
|
paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat; |
|
paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate; |
|
|
|
port->SetPortVideoParam(¶mPortFormat, true); |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { |
|
this->ports[OUTPORT_INDEX] = new PortVideo; |
|
if (this->ports[OUTPORT_INDEX] == NULL) { |
|
return OMX_ErrorInsufficientResources; |
|
} |
|
|
|
PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); |
|
|
|
// OMX_VIDEO_PARAM_BITRATETYPE |
|
memset(&mParamBitrate, 0, sizeof(mParamBitrate)); |
|
SetTypeHeader(&mParamBitrate, sizeof(mParamBitrate)); |
|
mParamBitrate.nPortIndex = OUTPORT_INDEX; |
|
mParamBitrate.eControlRate = OMX_Video_ControlRateVariable; |
|
mParamBitrate.nTargetBitrate = 192000; // to be overridden |
|
|
|
// OMX_VIDEO_CONFIG_PRI_INFOTYPE |
|
memset(&mConfigPriInfo, 0, sizeof(mConfigPriInfo)); |
|
SetTypeHeader(&mConfigPriInfo, sizeof(mConfigPriInfo)); |
|
mConfigPriInfo.nPortIndex = OUTPORT_INDEX; |
|
mConfigPriInfo.nCapacity = 0; |
|
mConfigPriInfo.nHolder = NULL; |
|
|
|
// OMX_VIDEO_CONFIG_INTEL_BITRATETYPE |
|
memset(&mConfigIntelBitrate, 0, sizeof(mConfigIntelBitrate)); |
|
SetTypeHeader(&mConfigIntelBitrate, sizeof(mConfigIntelBitrate)); |
|
mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX; |
|
mConfigIntelBitrate.nMaxEncodeBitrate = 0; // Maximum bitrate |
|
mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95% |
|
mConfigIntelBitrate.nWindowSize = 0; // Window size in milliseconds allowed for bitrate to reach target |
|
mConfigIntelBitrate.nInitialQP = 0; // Initial QP for I frames |
|
mConfigIntelBitrate.nMinQP = 0; |
|
mConfigIntelBitrate.nMaxQP = 0; |
|
mConfigIntelBitrate.nFrameRate = 0; |
|
mConfigIntelBitrate.nTemporalID = 0; |
|
|
|
// OMX_VIDEO_CONFIG_BITRATETYPE |
|
memset(&mConfigBitrate, 0, sizeof(mConfigBitrate)); |
|
SetTypeHeader(&mConfigBitrate, sizeof(mConfigBitrate)); |
|
mConfigBitrate.nPortIndex = OUTPORT_INDEX; |
|
mConfigBitrate.nEncodeBitrate = 0; // Maximum bitrate |
|
|
|
// OMX_VIDEO_CONFIG_INTEL_AIR |
|
memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir)); |
|
SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir)); |
|
mConfigIntelAir.nPortIndex = OUTPORT_INDEX; |
|
mConfigIntelAir.bAirEnable = OMX_FALSE; |
|
mConfigIntelAir.bAirAuto = OMX_FALSE; |
|
mConfigIntelAir.nAirMBs = 0; |
|
mConfigIntelAir.nAirThreshold = 0; |
|
|
|
// OMX_VIDEO_CONFIG_INTEL_AIR |
|
memset(&mParamVideoRefresh, 0, sizeof(mParamVideoRefresh)); |
|
SetTypeHeader(&mParamVideoRefresh, sizeof(mParamVideoRefresh)); |
|
mParamVideoRefresh.nPortIndex = OUTPORT_INDEX; |
|
mParamVideoRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshAdaptive; |
|
mParamVideoRefresh.nAirMBs = 0; |
|
mParamVideoRefresh.nAirRef = 0; |
|
mParamVideoRefresh.nCirMBs = 0; |
|
|
|
// OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESH |
|
memset(&mConfigAndroidIntraRefresh, 0, sizeof(mConfigAndroidIntraRefresh)); |
|
SetTypeHeader(&mConfigAndroidIntraRefresh, sizeof(mConfigAndroidIntraRefresh)); |
|
mConfigAndroidIntraRefresh.nPortIndex = OUTPORT_INDEX; |
|
mConfigAndroidIntraRefresh.nRefreshPeriod = 0; // default feature closed |
|
|
|
// OMX_CONFIG_FRAMERATETYPE |
|
memset(&mConfigFramerate, 0, sizeof(mConfigFramerate)); |
|
SetTypeHeader(&mConfigFramerate, sizeof(mConfigFramerate)); |
|
mConfigFramerate.nPortIndex = OUTPORT_INDEX; |
|
mConfigFramerate.xEncodeFramerate = 0; // Q16 format |
|
|
|
// OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL |
|
memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl)); |
|
SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl)); |
|
mParamIntelAdaptiveSliceControl.nPortIndex = OUTPORT_INDEX; |
|
mParamIntelAdaptiveSliceControl.bEnable = OMX_FALSE; |
|
mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5; |
|
mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8; |
|
mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200; |
|
|
|
// OMX_VIDEO_PARAM_PROFILELEVELTYPE |
|
memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel)); |
|
SetTypeHeader(&mParamProfileLevel, sizeof(mParamProfileLevel)); |
|
mParamProfileLevel.nPortIndex = OUTPORT_INDEX; |
|
mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden |
|
mParamProfileLevel.eLevel = 0; // undefined level, to be overridden |
|
|
|
// OMX_PARAM_PORTDEFINITIONTYPE |
|
OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; |
|
memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); |
|
SetTypeHeader(¶mPortDefinitionOutput, sizeof(paramPortDefinitionOutput)); |
|
paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX; |
|
paramPortDefinitionOutput.eDir = OMX_DirOutput; |
|
paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; // to be overridden |
|
paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; |
|
paramPortDefinitionOutput.nBufferSize = OUTPORT_BUFFER_SIZE; // to be overridden |
|
paramPortDefinitionOutput.bEnabled = OMX_TRUE; |
|
paramPortDefinitionOutput.bPopulated = OMX_FALSE; |
|
paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo; |
|
paramPortDefinitionOutput.format.video.cMIMEType = NULL; // to be overridden |
|
paramPortDefinitionOutput.format.video.pNativeRender = NULL; |
|
paramPortDefinitionOutput.format.video.nFrameWidth = 176; |
|
paramPortDefinitionOutput.format.video.nFrameHeight = 144; |
|
paramPortDefinitionOutput.format.video.nStride = 176; |
|
paramPortDefinitionOutput.format.video.nSliceHeight = 144; |
|
paramPortDefinitionOutput.format.video.nBitrate = 64000; |
|
paramPortDefinitionOutput.format.video.xFramerate = 15 << 16; |
|
paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE; |
|
paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden |
|
paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatUnused; |
|
paramPortDefinitionOutput.format.video.pNativeWindow = NULL; |
|
paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE; |
|
paramPortDefinitionOutput.nBufferAlignment = 0; |
|
|
|
InitOutputPortFormatSpecific(¶mPortDefinitionOutput); |
|
|
|
port->SetPortDefinition(¶mPortDefinitionOutput, true); |
|
port->SetPortBitrateParam(&mParamBitrate, true); |
|
|
|
// OMX_VIDEO_PARAM_PORTFORMATTYPE |
|
OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; |
|
memset(¶mPortFormat, 0, sizeof(paramPortFormat)); |
|
SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); |
|
paramPortFormat.nPortIndex = OUTPORT_INDEX; |
|
paramPortFormat.nIndex = 0; |
|
paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat; |
|
paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat; |
|
paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate; |
|
|
|
port->SetPortVideoParam(¶mPortFormat, true); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) { |
|
// no format specific to initialize input |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() { |
|
|
|
Encode_Status ret = ENCODE_SUCCESS; |
|
PortVideo *port_in = NULL; |
|
const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = NULL; |
|
LOGV("OMXVideoEncoderBase::SetVideoEncoderParam called\n"); |
|
|
|
port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]); |
|
paramPortDefinitionInput = port_in->GetPortDefinition(); |
|
mEncoderParams->resolution.height = paramPortDefinitionInput->format.video.nFrameHeight; |
|
mEncoderParams->resolution.width = paramPortDefinitionInput->format.video.nFrameWidth; |
|
|
|
mEncoderParams->frameRate.frameRateDenom = 1; |
|
if(mConfigFramerate.xEncodeFramerate != 0) { |
|
mEncoderParams->frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate; |
|
} else { |
|
mEncoderParams->frameRate.frameRateNum = paramPortDefinitionInput->format.video.xFramerate >> 16; |
|
mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16; |
|
} |
|
|
|
if(mEncoderParams->intraPeriod == 0) { |
|
OMX_U32 intraPeriod = mEncoderParams->frameRate.frameRateNum / 2; |
|
mEncoderParams->intraPeriod = (intraPeriod < 15) ? 15 : intraPeriod; // Limit intra frame period to ensure video quality for low bitrate application. |
|
} |
|
|
|
if (paramPortDefinitionInput->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) |
|
mEncoderParams->rawFormat = RAW_FORMAT_OPAQUE; |
|
else |
|
mEncoderParams->rawFormat = RAW_FORMAT_NV12; |
|
|
|
LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom); |
|
LOGV("frameRate.frameRateNum = %d\n", mEncoderParams->frameRate.frameRateNum); |
|
LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod); |
|
mEncoderParams->rcParams.initQP = mConfigIntelBitrate.nInitialQP; |
|
mEncoderParams->rcParams.minQP = mConfigIntelBitrate.nMinQP; |
|
mEncoderParams->rcParams.maxQP = 0; |
|
mEncoderParams->rcParams.I_minQP = 0; |
|
mEncoderParams->rcParams.I_maxQP = 0; |
|
mEncoderParams->rcParams.windowSize = mConfigIntelBitrate.nWindowSize; |
|
mEncoderParams->rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage; |
|
mEncoderParams->rcParams.enableIntraFrameQPControl = 0; |
|
|
|
mEncoderParams->rcParams.bitRate = mParamBitrate.nTargetBitrate; |
|
if ((mParamBitrate.eControlRate == OMX_Video_ControlRateConstant )|| |
|
(mParamBitrate.eControlRate == OMX_Video_ControlRateConstantSkipFrames)) { |
|
LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateConstant", __func__); |
|
mEncoderParams->rcMode = RATE_CONTROL_CBR; |
|
} else if ((mParamBitrate.eControlRate == OMX_Video_ControlRateVariable) || |
|
(mParamBitrate.eControlRate == OMX_Video_ControlRateVariableSkipFrames)) { |
|
LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVariable", __func__); |
|
mEncoderParams->rcMode = RATE_CONTROL_VBR; |
|
} else if (mParamBitrate.eControlRate == (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) { |
|
LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode ", __func__); |
|
mEncoderParams->rcMode = RATE_CONTROL_VCM; |
|
if(mConfigIntelBitrate.nMaxEncodeBitrate >0) |
|
mEncoderParams->rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate; |
|
if(mConfigIntelAir.bAirEnable == OMX_TRUE) { |
|
mEncoderParams->airParams.airAuto = mConfigIntelAir.bAirAuto; |
|
mEncoderParams->airParams.airMBs = mConfigIntelAir.nAirMBs; |
|
mEncoderParams->airParams.airThreshold = mConfigIntelAir.nAirThreshold; |
|
mEncoderParams->refreshType = VIDEO_ENC_AIR; |
|
} else { |
|
mEncoderParams->refreshType = VIDEO_ENC_NONIR; |
|
} |
|
LOGV("refreshType = %d\n", mEncoderParams->refreshType); |
|
} else { |
|
mEncoderParams->rcMode = RATE_CONTROL_NONE; |
|
} |
|
|
|
ret = mVideoEncoder->setParameters(mEncoderParams); |
|
CHECK_ENCODE_STATUS("setParameters"); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) { |
|
OMX_ERRORTYPE ret = OMX_ErrorNone; |
|
ret = SetVideoEncoderParam(); |
|
CHECK_STATUS("SetVideoEncoderParam"); |
|
|
|
Encode_Status status = mVideoEncoder->start(); |
|
if (status != ENCODE_SUCCESS) { |
|
LOGE("Start failed, status = 0x%08x\n", status); |
|
return OMX_ErrorUndefined; |
|
} |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) { |
|
if(mVideoEncoder) { |
|
mVideoEncoder->stop(); |
|
} |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) { |
|
|
|
this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); |
|
return OMX_ErrorNone; |
|
} |
|
OMX_ERRORTYPE OMXVideoEncoderBase:: ProcessorProcess( |
|
OMX_BUFFERHEADERTYPE **, |
|
buffer_retain_t *, |
|
OMX_U32) { |
|
|
|
LOGV("OMXVideoEncoderBase:: ProcessorProcess \n"); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) { |
|
LOGV("OMXVideoEncoderBase::ProcessorFlush\n"); |
|
if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { |
|
this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); |
|
mVideoEncoder->flush(); |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) { |
|
OMXComponentCodecBase::BuildHandlerList(); |
|
AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); |
|
AddHandler(OMX_IndexParamVideoBitrate, GetParamVideoBitrate, SetParamVideoBitrate); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoIntraRefresh, GetParamVideoIntraRefresh, SetParamVideoIntraRefresh); |
|
AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate); |
|
AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh); |
|
//AddHandler(OMX_IndexParamIntelAdaptiveSliceControl, GetParamIntelAdaptiveSliceControl, SetParamIntelAdaptiveSliceControl); |
|
//AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexStoreMetaDataInBuffers, GetStoreMetaDataInBuffers, SetStoreMetaDataInBuffers); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexExtSyncEncoding, GetSyncEncoding, SetSyncEncoding); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexExtPrependSPSPPS, GetPrependSPSPPS, SetPrependSPSPPS); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexExtTemporalLayer, GetTemporalLayer,SetTemporalLayer); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoBitrate, GetConfigVideoBitrate, SetConfigVideoBitrate); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexExtRequestBlackFramePointer, GetBlackFramePointer, GetBlackFramePointer); |
|
AddHandler((OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, GetConfigAndroidIntraRefresh, SetConfigAndroidIntraRefresh); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_U32 index; |
|
OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX_RANGE(p); |
|
CHECK_ENUMERATION_RANGE(p->nIndex, 2); |
|
|
|
PortVideo *port = NULL; |
|
port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); |
|
index = p->nIndex; |
|
memcpy(p, port->GetPortVideoParam(), sizeof(*p)); |
|
// port supports OMX_COLOR_FormatYUV420SemiPlanar & OMX_COLOR_FormatAndroidOpaque |
|
if (index == 1) { |
|
p->nIndex = 1; |
|
p->eColorFormat = OMX_COLOR_FormatAndroidOpaque; |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX_RANGE(p); |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
// TODO: do we need to check if port is enabled? |
|
PortVideo *port = NULL; |
|
port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); |
|
#if 0 |
|
if (p->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { |
|
p->nIndex = 0; |
|
p->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; |
|
} |
|
#endif |
|
port->SetPortVideoParam(p, false); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoBitrate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mParamBitrate, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
CHECK_SET_PARAM_STATE(); |
|
OMX_U32 index = p->nPortIndex; |
|
PortVideo *port = NULL; |
|
// This disables other type of bitrate control mechanism |
|
// TODO: check if it is desired |
|
|
|
// TODO: can we override mParamBitrate.nPortIndex (See SetPortBitrateParam) |
|
mParamBitrate.eControlRate = p->eControlRate; |
|
mParamBitrate.nTargetBitrate = p->nTargetBitrate; |
|
|
|
port = static_cast<PortVideo *>(ports[index]); |
|
ret = port->SetPortBitrateParam(p, false); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetIntelPrivateInfo(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mConfigPriInfo, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetIntelPrivateInfo(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// OMX_VIDEO_CONFIG_PRI_INFOTYPE is static parameter? |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
// TODO: can we override mConfigPriInfo.nPortIndex (See SetPortPrivateInfoParam) |
|
|
|
if(p->nHolder != NULL) { |
|
// TODO: do we need to free nHolder? |
|
if (mConfigPriInfo.nHolder) { |
|
free(mConfigPriInfo.nHolder); |
|
} |
|
mConfigPriInfo.nCapacity = p->nCapacity; |
|
// TODO: nCapacity is in 8-bit unit or 32-bit unit? |
|
// TODO: check memory allocation |
|
mConfigPriInfo.nHolder = (OMX_PTR)malloc(sizeof(OMX_U32) * p->nCapacity); |
|
memcpy(mConfigPriInfo.nHolder, p->nHolder, sizeof(OMX_U32) * p->nCapacity); |
|
} else { |
|
mConfigPriInfo.nCapacity = 0; |
|
mConfigPriInfo.nHolder = NULL; |
|
} |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mConfigIntelBitrate, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){ |
|
LOGE("SetConfigIntelBitrate failed. Feature is disabled."); |
|
return OMX_ErrorUnsupportedIndex; |
|
} |
|
OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mConfigIntelBitrate = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_CONFIG_STATE(); |
|
|
|
VideoConfigBitRate configBitRate; |
|
configBitRate.rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate; |
|
configBitRate.rcParams.initQP = mConfigIntelBitrate.nInitialQP; |
|
configBitRate.rcParams.minQP = mConfigIntelBitrate.nMinQP; |
|
configBitRate.rcParams.maxQP = mConfigIntelBitrate.nMaxQP; |
|
configBitRate.rcParams.I_minQP = 0; |
|
configBitRate.rcParams.I_maxQP = 0; |
|
configBitRate.rcParams.windowSize = mConfigIntelBitrate.nWindowSize; |
|
configBitRate.rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage; |
|
configBitRate.rcParams.enableIntraFrameQPControl = 0; |
|
configBitRate.rcParams.temporalFrameRate = mConfigIntelBitrate.nFrameRate; |
|
configBitRate.rcParams.temporalID = mConfigIntelBitrate.nTemporalID; |
|
retStatus = mVideoEncoder->setConfig(&configBitRate); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("failed to set IntelBitrate"); |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mConfigIntelAir, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
|
|
OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mConfigIntelAir = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_CONFIG_STATE(); |
|
|
|
VideoConfigAIR configAIR; |
|
VideoConfigIntraRefreshType configIntraRefreshType; |
|
if(mConfigIntelAir.bAirEnable == OMX_TRUE) { |
|
configAIR.airParams.airAuto = mConfigIntelAir.bAirAuto; |
|
configAIR.airParams.airMBs = mConfigIntelAir.nAirMBs; |
|
configAIR.airParams.airThreshold = mConfigIntelAir.nAirThreshold; |
|
configIntraRefreshType.refreshType = VIDEO_ENC_AIR; |
|
} else { |
|
configIntraRefreshType.refreshType = VIDEO_ENC_NONIR; |
|
} |
|
|
|
retStatus = mVideoEncoder->setConfig(&configAIR); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set AIR config"); |
|
} |
|
|
|
retStatus = mVideoEncoder->setConfig(&configIntraRefreshType); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set refresh config"); |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoIntraRefresh(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mParamVideoRefresh, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoIntraRefresh(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
|
|
OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mParamVideoRefresh = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
VideoConfigIntraRefreshType configIntraRefreshType; |
|
configIntraRefreshType.refreshType = (VideoIntraRefreshType)(mParamVideoRefresh.eRefreshMode + 1); |
|
if(configIntraRefreshType.refreshType == VIDEO_ENC_CIR){ |
|
VideoConfigCIR configCIR; |
|
VideoConfigIntraRefreshType configIntraRefreshType; |
|
configCIR.cirParams.cir_num_mbs = mParamVideoRefresh.nCirMBs; |
|
configIntraRefreshType.refreshType = VIDEO_ENC_CIR; |
|
|
|
retStatus = mVideoEncoder->setConfig(&configCIR); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set CIR config"); |
|
} |
|
}else{ |
|
VideoConfigAIR configAIR; |
|
|
|
configAIR.airParams.airMBs = mParamVideoRefresh.nAirMBs; |
|
configAIR.airParams.airThreshold = mParamVideoRefresh.nAirRef; |
|
|
|
retStatus = mVideoEncoder->setConfig(&configAIR); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set AIR config"); |
|
} |
|
|
|
} |
|
|
|
retStatus = mVideoEncoder->setConfig(&configIntraRefreshType); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set refresh config"); |
|
} |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mConfigFramerate, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){ |
|
LOGE("SetConfigVideoFramerate failed. Feature is disabled."); |
|
return OMX_ErrorUnsupportedIndex; |
|
} |
|
OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mConfigFramerate = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO, return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_CONFIG_STATE(); |
|
|
|
VideoConfigFrameRate framerate; |
|
framerate.frameRate.frameRateDenom = 1; |
|
framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate >> 16; |
|
retStatus = mVideoEncoder->setConfig(&framerate); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set frame rate config"); |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR) { |
|
LOGW("GetConfigVideoIntraVOPRefresh is not supported."); |
|
return OMX_ErrorUnsupportedSetting; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_CONFIG_STATE(); |
|
|
|
if(p->IntraRefreshVOP == OMX_TRUE) { |
|
VideoParamConfigSet configIDRRequest; |
|
configIDRRequest.type = VideoConfigTypeIDRRequest; |
|
retStatus = mVideoEncoder->setConfig(&configIDRRequest); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("Failed to set refresh config"); |
|
} |
|
} |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { |
|
|
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mParamIntelAdaptiveSliceControl, sizeof(*p)); |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { |
|
|
|
OMX_ERRORTYPE ret; |
|
if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) { |
|
LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled."); |
|
return OMX_ErrorUnsupportedIndex; |
|
} |
|
OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set only in Loaded state (ComponentSetParam) |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
mParamIntelAdaptiveSliceControl = *p; |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
/* |
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// assign values instead of memory coping to avoid nProfileIndex being overridden |
|
p->eProfile = mParamProfileLevel.eProfile; |
|
p->eLevel = mParamProfileLevel.eLevel; |
|
|
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) { |
|
LOGW("SetParamVideoProfileLevelQuerySupported is not supported."); |
|
return OMX_ErrorUnsupportedSetting; |
|
} |
|
*/ |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetStoreMetaDataInBuffers(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, INPORT_INDEX); |
|
|
|
p->bStoreMetaData = mStoreMetaDataInBuffers; |
|
|
|
return OMX_ErrorNone; |
|
}; |
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetStoreMetaDataInBuffers(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure; |
|
VideoParamsStoreMetaDataInBuffers StoreMetaDataInBuffers; |
|
PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, INPORT_INDEX); |
|
|
|
LOGD("SetStoreMetaDataInBuffers (enabled = %x)", p->bStoreMetaData); |
|
if(mStoreMetaDataInBuffers == p->bStoreMetaData) |
|
return OMX_ErrorNone; |
|
|
|
StoreMetaDataInBuffers.isEnabled = p->bStoreMetaData; |
|
if (mVideoEncoder->setParameters(&StoreMetaDataInBuffers) != ENCODE_SUCCESS) |
|
return OMX_ErrorNotReady; |
|
|
|
mStoreMetaDataInBuffers = p->bStoreMetaData; |
|
|
|
if(mStoreMetaDataInBuffers){ |
|
// for input port buffer |
|
OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput; |
|
const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get; |
|
|
|
paramPortDefinitionInput_get = port->GetPortDefinition(); |
|
paramPortDefinitionInput = (OMX_PARAM_PORTDEFINITIONTYPE *)paramPortDefinitionInput_get; |
|
paramPortDefinitionInput->nBufferSize = IntelMetadataBuffer::GetMaxBufferSize(); |
|
} |
|
else |
|
{ |
|
const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get; |
|
|
|
paramPortDefinitionInput_get = port->GetPortDefinition(); |
|
port->SetPortDefinition(paramPortDefinitionInput_get, true); |
|
} |
|
|
|
LOGD("SetStoreMetaDataInBuffers success"); |
|
return OMX_ErrorNone; |
|
}; |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetSyncEncoding(OMX_PTR pStructure) { |
|
OMX_BOOL* syncEncoding = static_cast<OMX_BOOL*>(pStructure); |
|
|
|
*syncEncoding = mSyncEncoding; |
|
|
|
return OMX_ErrorNone; |
|
}; |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetSyncEncoding(OMX_PTR pStructure) { |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
mSyncEncoding = *(static_cast<OMX_BOOL*>(pStructure)); |
|
|
|
LOGD("SetSyncEncoding %d", mSyncEncoding); |
|
|
|
return OMX_ErrorNone; |
|
}; |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetPrependSPSPPS(OMX_PTR) { |
|
return OMX_ErrorNone; |
|
}; |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetPrependSPSPPS(OMX_PTR) { |
|
LOGD("SetPrependSPSPPS success"); |
|
return OMX_ErrorNone; |
|
}; |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetTemporalLayer(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER* p = static_cast<OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER*>(pStructure); |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mTemporalLayer, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetTemporalLayer(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *p = (OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *)pStructure; |
|
VideoParamsTemporalLayer TemporalLayer; |
|
OMX_U32 i; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
LOGE("SetTemporalLayer (enabled = %d)", p->nNumberOfTemporalLayer); |
|
|
|
TemporalLayer.numberOfLayer = p->nNumberOfTemporalLayer; |
|
TemporalLayer.nPeriodicity = p->nPeriodicity; |
|
for(i=0;i<p->nPeriodicity;i++) |
|
TemporalLayer.nLayerID[i] = p->nLayerID[i]; |
|
|
|
if (mVideoEncoder->setParameters(&TemporalLayer) != ENCODE_SUCCESS) |
|
return OMX_ErrorNotReady; |
|
|
|
LOGE("SetTemporalLayer success"); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetBlackFramePointer(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *p = (OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, INPORT_INDEX); |
|
|
|
PortVideo *port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]); |
|
const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = port_in->GetPortDefinition(); |
|
OMX_U32 width = paramPortDefinitionInput->format.video.nFrameWidth; |
|
OMX_U32 height = paramPortDefinitionInput->format.video.nFrameHeight; |
|
OMX_U32 lumaSize = width * height; |
|
OMX_U32 bufferSize = width * height * 3 / 2; |
|
|
|
if(mBlackFramePointer) { |
|
free(mBlackFramePointer); |
|
mBlackFramePointer = NULL; |
|
} else { |
|
mBlackFramePointer = (OMX_PTR)memalign(4096, bufferSize); // align to page size |
|
if(!mBlackFramePointer) { |
|
return OMX_ErrorInsufficientResources; |
|
} |
|
memset(mBlackFramePointer, 0x0, lumaSize); |
|
memset((OMX_PTR)((uint64_t)mBlackFramePointer + lumaSize), 0x80, lumaSize / 2); |
|
p->nFramePointer = (OMX_U32)mBlackFramePointer; |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetBlackFramePointer(OMX_PTR) { |
|
return OMX_ErrorUnsupportedSetting; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoBitrate(OMX_PTR pStructure) { |
|
|
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
memcpy(p, &mConfigBitrate, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoBitrate(OMX_PTR pStructure){ |
|
OMX_ERRORTYPE ret; |
|
Encode_Status retStatus = ENCODE_SUCCESS; |
|
if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){ |
|
LOGE("SetConfigIntelBitrate failed. Feature is disabled."); |
|
return OMX_ErrorUnsupportedIndex; |
|
} |
|
OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure; |
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mConfigBitrate = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
// CHECK_SET_CONFIG_STATE(); |
|
|
|
VideoConfigBitRate configBitRate; |
|
configBitRate.rcParams.bitRate = mConfigBitrate.nEncodeBitrate; |
|
configBitRate.rcParams.temporalID = 0; |
|
retStatus = mVideoEncoder->setConfig(&configBitRate); |
|
if(retStatus != ENCODE_SUCCESS) { |
|
LOGW("failed to set IntelBitrate"); |
|
} |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigAndroidIntraRefresh(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
memcpy(p, &mConfigAndroidIntraRefresh, sizeof(*p)); |
|
return OMX_ErrorNone; |
|
} |
|
|
|
OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigAndroidIntraRefresh(OMX_PTR pStructure) { |
|
OMX_ERRORTYPE ret; |
|
|
|
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure; |
|
|
|
CHECK_TYPE_HEADER(p); |
|
CHECK_PORT_INDEX(p, OUTPORT_INDEX); |
|
|
|
// set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) |
|
mConfigAndroidIntraRefresh = *p; |
|
|
|
// return OMX_ErrorNone if not in Executing state |
|
// TODO: return OMX_ErrorIncorrectStateOperation? |
|
CHECK_SET_PARAM_STATE(); |
|
|
|
OMX_VIDEO_PARAM_INTRAREFRESHTYPE intraRefresh; |
|
memset(&intraRefresh, 0, sizeof(intraRefresh)); |
|
intraRefresh.nSize = sizeof(intraRefresh); |
|
intraRefresh.nVersion = p->nVersion; |
|
intraRefresh.nPortIndex = mConfigAndroidIntraRefresh.nPortIndex; |
|
intraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; |
|
intraRefresh.nAirMBs = 0; |
|
intraRefresh.nAirRef = 0; |
|
|
|
if (0 == mConfigAndroidIntraRefresh.nRefreshPeriod) { |
|
intraRefresh.nCirMBs = 0; |
|
} else { |
|
OMX_PARAM_PORTDEFINITIONTYPE def; |
|
|
|
if (intraRefresh.nPortIndex < nr_ports) { |
|
memcpy(&def, ports[intraRefresh.nPortIndex]->GetPortDefinition(),sizeof(def)); |
|
} else { |
|
LOGW("Failed tp set AIR config, bad port index"); |
|
return OMX_ErrorBadPortIndex; |
|
} |
|
|
|
intraRefresh.nCirMBs = divUp((divUp(def.format.video.nFrameWidth, 16u) * divUp(def.format.video.nFrameHeight,16u)), mConfigAndroidIntraRefresh.nRefreshPeriod); |
|
} |
|
return SetParamVideoIntraRefresh(&intraRefresh); |
|
}
|
|
|