1034 lines
40 KiB
C++
1034 lines
40 KiB
C++
/*
|
|
* 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);
|
|
}
|