1 /*
2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 
18 #define LOG_TAG "OMXVideoEncoderBase"
19 #include "OMXVideoEncoderBase.h"
20 #include "IntelMetadataBuffer.h"
21 #include <cutils/properties.h>
22 #include <wrs_omxil_core/log.h>
23 
24 static const char *RAW_MIME_TYPE = "video/raw";
25 
OMXVideoEncoderBase()26 OMXVideoEncoderBase::OMXVideoEncoderBase()
27     :mVideoEncoder(NULL)
28     ,mEncoderParams(NULL)
29     ,mFrameInputCount(0)
30     ,mFrameOutputCount(0)
31     ,mFirstFrame(OMX_TRUE)
32     ,mFrameRetrieved(OMX_TRUE)
33     ,mStoreMetaDataInBuffers(OMX_FALSE)
34     ,mSyncEncoding(OMX_TRUE)
35     ,mOmxLogLevel(0)
36     ,mBlackFramePointer(NULL) {
37     mEncoderParams = new VideoParamsCommon();
38     if (!mEncoderParams) LOGE("OMX_ErrorInsufficientResources");
39 
40     char logLevelProp[128];
41     if (property_get("omxenc.debug", logLevelProp, NULL)) {
42         mOmxLogLevel = atoi(logLevelProp);
43         LOGD("Debug level is %d", mOmxLogLevel);
44     }
45 
46     LOGV("OMXVideoEncoderBase::OMXVideoEncoderBase end");
47 }
48 
~OMXVideoEncoderBase()49 OMXVideoEncoderBase::~OMXVideoEncoderBase() {
50 
51     // destroy ports
52     if (this->ports) {
53         if (this->ports[INPORT_INDEX]) {
54             delete this->ports[INPORT_INDEX];
55             this->ports[INPORT_INDEX] = NULL;
56         }
57 
58         if (this->ports[OUTPORT_INDEX]) {
59             delete this->ports[OUTPORT_INDEX];
60             this->ports[OUTPORT_INDEX] = NULL;
61         }
62     }
63 
64     if (mBlackFramePointer) {
65         free(mBlackFramePointer);
66         mBlackFramePointer = NULL;
67     }
68     // Release video encoder object
69     if(mVideoEncoder) {
70         releaseVideoEncoder(mVideoEncoder);
71         mVideoEncoder = NULL;
72     }
73 
74     if(mEncoderParams) {
75         delete mEncoderParams;
76         mEncoderParams = NULL;
77     }
78 
79 }
80 
InitInputPort(void)81 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) {
82     this->ports[INPORT_INDEX] = new PortVideo;
83     if (this->ports[INPORT_INDEX] == NULL) {
84         return OMX_ErrorInsufficientResources;
85     }
86 
87     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
88 
89     // OMX_PARAM_PORTDEFINITIONTYPE
90     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
91     memset(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
92     SetTypeHeader(&paramPortDefinitionInput, sizeof(paramPortDefinitionInput));
93     paramPortDefinitionInput.nPortIndex = INPORT_INDEX;
94     paramPortDefinitionInput.eDir = OMX_DirInput;
95     paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
96     paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
97     paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE;
98     paramPortDefinitionInput.bEnabled = OMX_TRUE;
99     paramPortDefinitionInput.bPopulated = OMX_FALSE;
100     paramPortDefinitionInput.eDomain = OMX_PortDomainVideo;
101     paramPortDefinitionInput.format.video.cMIMEType = (OMX_STRING)RAW_MIME_TYPE;
102     paramPortDefinitionInput.format.video.pNativeRender = NULL;
103     paramPortDefinitionInput.format.video.nFrameWidth = 176;
104     paramPortDefinitionInput.format.video.nFrameHeight = 144;
105     paramPortDefinitionInput.format.video.nStride = 0;
106     paramPortDefinitionInput.format.video.nSliceHeight = 0;
107     paramPortDefinitionInput.format.video.nBitrate = 64000;
108     paramPortDefinitionInput.format.video.xFramerate = 15 << 16;
109     paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE;
110     paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
111     paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
112     paramPortDefinitionInput.format.video.pNativeWindow = NULL;
113     paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE;
114     paramPortDefinitionInput.nBufferAlignment = 0;
115 
116     // Nothing specific to initialize input port.
117     InitInputPortFormatSpecific(&paramPortDefinitionInput);
118 
119     port->SetPortDefinition(&paramPortDefinitionInput, true);
120 
121     // Set port buffer 4k aligned
122     port->SetMemAlignment(4096);
123 
124     // OMX_VIDEO_PARAM_PORTFORMATTYPE
125     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
126     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
127     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
128     paramPortFormat.nPortIndex = INPORT_INDEX;
129     paramPortFormat.nIndex = 0;
130     paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat;
131     paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat;
132     paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate;
133 
134     port->SetPortVideoParam(&paramPortFormat, true);
135 
136     return OMX_ErrorNone;
137 }
138 
139 
InitOutputPort(void)140 OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) {
141     this->ports[OUTPORT_INDEX] = new PortVideo;
142     if (this->ports[OUTPORT_INDEX] == NULL) {
143         return OMX_ErrorInsufficientResources;
144     }
145 
146     PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
147 
148     // OMX_VIDEO_PARAM_BITRATETYPE
149     memset(&mParamBitrate, 0, sizeof(mParamBitrate));
150     SetTypeHeader(&mParamBitrate, sizeof(mParamBitrate));
151     mParamBitrate.nPortIndex = OUTPORT_INDEX;
152     mParamBitrate.eControlRate = OMX_Video_ControlRateVariable;
153     mParamBitrate.nTargetBitrate = 192000; // to be overridden
154 
155     // OMX_VIDEO_CONFIG_PRI_INFOTYPE
156     memset(&mConfigPriInfo, 0, sizeof(mConfigPriInfo));
157     SetTypeHeader(&mConfigPriInfo, sizeof(mConfigPriInfo));
158     mConfigPriInfo.nPortIndex = OUTPORT_INDEX;
159     mConfigPriInfo.nCapacity = 0;
160     mConfigPriInfo.nHolder = NULL;
161 
162     // OMX_VIDEO_CONFIG_INTEL_BITRATETYPE
163     memset(&mConfigIntelBitrate, 0, sizeof(mConfigIntelBitrate));
164     SetTypeHeader(&mConfigIntelBitrate, sizeof(mConfigIntelBitrate));
165     mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX;
166     mConfigIntelBitrate.nMaxEncodeBitrate = 0; // Maximum bitrate
167     mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95%
168     mConfigIntelBitrate.nWindowSize = 0; // Window size in milliseconds allowed for bitrate to reach target
169     mConfigIntelBitrate.nInitialQP = 0;  // Initial QP for I frames
170     mConfigIntelBitrate.nMinQP = 0;
171     mConfigIntelBitrate.nMaxQP = 0;
172     mConfigIntelBitrate.nFrameRate = 0;
173     mConfigIntelBitrate.nTemporalID = 0;
174 
175     // OMX_VIDEO_CONFIG_BITRATETYPE
176     memset(&mConfigBitrate, 0, sizeof(mConfigBitrate));
177     SetTypeHeader(&mConfigBitrate, sizeof(mConfigBitrate));
178     mConfigBitrate.nPortIndex = OUTPORT_INDEX;
179     mConfigBitrate.nEncodeBitrate = 0; // Maximum bitrate
180 
181     // OMX_VIDEO_CONFIG_INTEL_AIR
182     memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir));
183     SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir));
184     mConfigIntelAir.nPortIndex = OUTPORT_INDEX;
185     mConfigIntelAir.bAirEnable = OMX_FALSE;
186     mConfigIntelAir.bAirAuto = OMX_FALSE;
187     mConfigIntelAir.nAirMBs = 0;
188     mConfigIntelAir.nAirThreshold = 0;
189 
190     // OMX_VIDEO_CONFIG_INTEL_AIR
191     memset(&mParamVideoRefresh, 0, sizeof(mParamVideoRefresh));
192     SetTypeHeader(&mParamVideoRefresh, sizeof(mParamVideoRefresh));
193     mParamVideoRefresh.nPortIndex = OUTPORT_INDEX;
194     mParamVideoRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshAdaptive;
195     mParamVideoRefresh.nAirMBs = 0;
196     mParamVideoRefresh.nAirRef = 0;
197     mParamVideoRefresh.nCirMBs = 0;
198 
199     // OMX_CONFIG_FRAMERATETYPE
200     memset(&mConfigFramerate, 0, sizeof(mConfigFramerate));
201     SetTypeHeader(&mConfigFramerate, sizeof(mConfigFramerate));
202     mConfigFramerate.nPortIndex = OUTPORT_INDEX;
203     mConfigFramerate.xEncodeFramerate =  0; // Q16 format
204 
205     // OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL
206     memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl));
207     SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl));
208     mParamIntelAdaptiveSliceControl.nPortIndex = OUTPORT_INDEX;
209     mParamIntelAdaptiveSliceControl.bEnable = OMX_FALSE;
210     mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5;
211     mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8;
212     mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200;
213 
214     // OMX_VIDEO_PARAM_PROFILELEVELTYPE
215     memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel));
216     SetTypeHeader(&mParamProfileLevel, sizeof(mParamProfileLevel));
217     mParamProfileLevel.nPortIndex = OUTPORT_INDEX;
218     mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden
219     mParamProfileLevel.eLevel = 0; // undefined level, to be overridden
220 
221     // OMX_PARAM_PORTDEFINITIONTYPE
222     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput;
223     memset(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
224     SetTypeHeader(&paramPortDefinitionOutput, sizeof(paramPortDefinitionOutput));
225     paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX;
226     paramPortDefinitionOutput.eDir = OMX_DirOutput;
227     paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; // to be overridden
228     paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
229     paramPortDefinitionOutput.nBufferSize = OUTPORT_BUFFER_SIZE; // to be overridden
230     paramPortDefinitionOutput.bEnabled = OMX_TRUE;
231     paramPortDefinitionOutput.bPopulated = OMX_FALSE;
232     paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo;
233     paramPortDefinitionOutput.format.video.cMIMEType = NULL; // to be overridden
234     paramPortDefinitionOutput.format.video.pNativeRender = NULL;
235     paramPortDefinitionOutput.format.video.nFrameWidth = 176;
236     paramPortDefinitionOutput.format.video.nFrameHeight = 144;
237     paramPortDefinitionOutput.format.video.nStride = 176;
238     paramPortDefinitionOutput.format.video.nSliceHeight = 144;
239     paramPortDefinitionOutput.format.video.nBitrate = 64000;
240     paramPortDefinitionOutput.format.video.xFramerate = 15 << 16;
241     paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE;
242     paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden
243     paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatUnused;
244     paramPortDefinitionOutput.format.video.pNativeWindow = NULL;
245     paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE;
246     paramPortDefinitionOutput.nBufferAlignment = 0;
247 
248     InitOutputPortFormatSpecific(&paramPortDefinitionOutput);
249 
250     port->SetPortDefinition(&paramPortDefinitionOutput, true);
251     port->SetPortBitrateParam(&mParamBitrate, true);
252 
253     // OMX_VIDEO_PARAM_PORTFORMATTYPE
254     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
255     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
256     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
257     paramPortFormat.nPortIndex = OUTPORT_INDEX;
258     paramPortFormat.nIndex = 0;
259     paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat;
260     paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat;
261     paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate;
262 
263     port->SetPortVideoParam(&paramPortFormat, true);
264     return OMX_ErrorNone;
265 }
266 
InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *)267 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
268     // no format specific to initialize input
269     return OMX_ErrorNone;
270 }
271 
SetVideoEncoderParam()272 OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() {
273 
274     Encode_Status ret = ENCODE_SUCCESS;
275     PortVideo *port_in = NULL;
276     PortVideo *port_out = NULL;
277     OMX_VIDEO_CONTROLRATETYPE controlrate;
278     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = NULL;
279     LOGV("OMXVideoEncoderBase::SetVideoEncoderParam called\n");
280 
281     port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]);
282     port_out = static_cast<PortVideo *>(ports[OUTPORT_INDEX]);
283     paramPortDefinitionInput = port_in->GetPortDefinition();
284     mEncoderParams->resolution.height = paramPortDefinitionInput->format.video.nFrameHeight;
285     mEncoderParams->resolution.width = paramPortDefinitionInput->format.video.nFrameWidth;
286     const OMX_VIDEO_PARAM_BITRATETYPE *bitrate = port_out->GetPortBitrateParam();
287 
288     mEncoderParams->frameRate.frameRateDenom = 1;
289     if(mConfigFramerate.xEncodeFramerate != 0) {
290         mEncoderParams->frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate;
291     } else {
292         mEncoderParams->frameRate.frameRateNum = paramPortDefinitionInput->format.video.xFramerate >> 16;
293         mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16;
294     }
295 
296     if(mEncoderParams->intraPeriod == 0) {
297         OMX_U32 intraPeriod = mEncoderParams->frameRate.frameRateNum / 2;
298         mEncoderParams->intraPeriod = (intraPeriod < 15) ? 15 : intraPeriod;   // Limit intra frame period to ensure video quality for low bitrate application.
299     }
300 
301     if (paramPortDefinitionInput->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque)
302         mEncoderParams->rawFormat = RAW_FORMAT_OPAQUE;
303     else
304         mEncoderParams->rawFormat = RAW_FORMAT_NV12;
305 
306     LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom);
307     LOGV("frameRate.frameRateNum = %d\n", mEncoderParams->frameRate.frameRateNum);
308     LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod);
309     mEncoderParams->rcParams.initQP = mConfigIntelBitrate.nInitialQP;
310     mEncoderParams->rcParams.minQP = mConfigIntelBitrate.nMinQP;
311     mEncoderParams->rcParams.maxQP = 0;
312     mEncoderParams->rcParams.I_minQP = 0;
313     mEncoderParams->rcParams.I_maxQP = 0;
314     mEncoderParams->rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
315     mEncoderParams->rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
316     mEncoderParams->rcParams.enableIntraFrameQPControl = 0;
317 
318     mEncoderParams->rcParams.bitRate = mParamBitrate.nTargetBitrate;
319     if ((mParamBitrate.eControlRate == OMX_Video_ControlRateConstant )||
320             (mParamBitrate.eControlRate == OMX_Video_ControlRateConstantSkipFrames)) {
321         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateConstant", __func__);
322         mEncoderParams->rcMode = RATE_CONTROL_CBR;
323     } else if ((mParamBitrate.eControlRate == OMX_Video_ControlRateVariable) ||
324             (mParamBitrate.eControlRate == OMX_Video_ControlRateVariableSkipFrames)) {
325         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVariable", __func__);
326         mEncoderParams->rcMode = RATE_CONTROL_VBR;
327     } else if (mParamBitrate.eControlRate == (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) {
328         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode ", __func__);
329         mEncoderParams->rcMode = RATE_CONTROL_VCM;
330         if(mConfigIntelBitrate.nMaxEncodeBitrate >0)
331             mEncoderParams->rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
332         if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
333             mEncoderParams->airParams.airAuto = mConfigIntelAir.bAirAuto;
334             mEncoderParams->airParams.airMBs = mConfigIntelAir.nAirMBs;
335             mEncoderParams->airParams.airThreshold = mConfigIntelAir.nAirThreshold;
336             mEncoderParams->refreshType = VIDEO_ENC_AIR;
337         } else {
338             mEncoderParams->refreshType = VIDEO_ENC_NONIR;
339         }
340         LOGV("refreshType = %d\n", mEncoderParams->refreshType);
341     } else {
342         mEncoderParams->rcMode = RATE_CONTROL_NONE;
343     }
344 
345     ret = mVideoEncoder->setParameters(mEncoderParams);
346     CHECK_ENCODE_STATUS("setParameters");
347     return OMX_ErrorNone;
348 }
349 
ProcessorInit(void)350 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) {
351     OMX_ERRORTYPE ret = OMX_ErrorNone;
352     ret = SetVideoEncoderParam();
353     CHECK_STATUS("SetVideoEncoderParam");
354 
355     Encode_Status status = mVideoEncoder->start();
356     if (status != ENCODE_SUCCESS) {
357         LOGE("Start failed, status = 0x%08x\n", status);
358         return OMX_ErrorUndefined;
359     }
360 
361     return OMX_ErrorNone;
362 }
363 
ProcessorDeinit(void)364 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) {
365     OMX_ERRORTYPE ret;
366 
367     if(mVideoEncoder) {
368         mVideoEncoder->stop();
369     }
370 
371     return OMX_ErrorNone;
372 }
373 
ProcessorStop(void)374 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) {
375 
376     this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
377     return OMX_ErrorNone;
378 }
ProcessorProcess(OMX_BUFFERHEADERTYPE **,buffer_retain_t *,OMX_U32)379 OMX_ERRORTYPE OMXVideoEncoderBase:: ProcessorProcess(
380     OMX_BUFFERHEADERTYPE **,
381     buffer_retain_t *,
382     OMX_U32) {
383 
384     LOGV("OMXVideoEncoderBase:: ProcessorProcess \n");
385     return OMX_ErrorNone;
386 }
387 
ProcessorFlush(OMX_U32 portIndex)388 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) {
389     LOGV("OMXVideoEncoderBase::ProcessorFlush\n");
390     if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
391         this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
392         mVideoEncoder->flush();
393     }
394     return OMX_ErrorNone;
395 }
396 
BuildHandlerList(void)397 OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) {
398     OMXComponentCodecBase::BuildHandlerList();
399     AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat);
400     AddHandler(OMX_IndexParamVideoBitrate, GetParamVideoBitrate, SetParamVideoBitrate);
401     AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo);
402     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate);
403     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR);
404     AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoIntraRefresh, GetParamVideoIntraRefresh, SetParamVideoIntraRefresh);
405     AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate);
406     AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh);
407     //AddHandler(OMX_IndexParamIntelAdaptiveSliceControl, GetParamIntelAdaptiveSliceControl, SetParamIntelAdaptiveSliceControl);
408     //AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported);
409     AddHandler((OMX_INDEXTYPE)OMX_IndexStoreMetaDataInBuffers, GetStoreMetaDataInBuffers, SetStoreMetaDataInBuffers);
410     AddHandler((OMX_INDEXTYPE)OMX_IndexExtSyncEncoding, GetSyncEncoding, SetSyncEncoding);
411     AddHandler((OMX_INDEXTYPE)OMX_IndexExtPrependSPSPPS, GetPrependSPSPPS, SetPrependSPSPPS);
412     AddHandler((OMX_INDEXTYPE)OMX_IndexExtTemporalLayer, GetTemporalLayer,SetTemporalLayer);
413     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoBitrate, GetConfigVideoBitrate, SetConfigVideoBitrate);
414     AddHandler((OMX_INDEXTYPE)OMX_IndexExtRequestBlackFramePointer, GetBlackFramePointer, GetBlackFramePointer);
415     return OMX_ErrorNone;
416 }
417 
GetParamVideoPortFormat(OMX_PTR pStructure)418 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) {
419     OMX_ERRORTYPE ret;
420     OMX_U32 index;
421     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
422 
423     CHECK_TYPE_HEADER(p);
424     CHECK_PORT_INDEX_RANGE(p);
425     CHECK_ENUMERATION_RANGE(p->nIndex, 2);
426 
427     PortVideo *port = NULL;
428     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
429     index = p->nIndex;
430     memcpy(p, port->GetPortVideoParam(), sizeof(*p));
431     // port supports OMX_COLOR_FormatYUV420SemiPlanar & OMX_COLOR_FormatAndroidOpaque
432     if (index == 1) {
433         p->nIndex = 1;
434         p->eColorFormat = OMX_COLOR_FormatAndroidOpaque;
435     }
436     return OMX_ErrorNone;
437 }
438 
SetParamVideoPortFormat(OMX_PTR pStructure)439 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) {
440     OMX_ERRORTYPE ret;
441     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
442 
443     CHECK_TYPE_HEADER(p);
444     CHECK_PORT_INDEX_RANGE(p);
445     CHECK_SET_PARAM_STATE();
446 
447     // TODO: do we need to check if port is enabled?
448     PortVideo *port = NULL;
449     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
450 #if 0
451     if (p->eColorFormat ==  OMX_COLOR_FormatAndroidOpaque) {
452         p->nIndex = 0;
453         p->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
454     }
455 #endif
456     port->SetPortVideoParam(p, false);
457     return OMX_ErrorNone;
458 }
459 
GetParamVideoBitrate(OMX_PTR pStructure)460 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoBitrate(OMX_PTR pStructure) {
461     OMX_ERRORTYPE ret;
462     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
463 
464     CHECK_TYPE_HEADER(p);
465     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
466     memcpy(p, &mParamBitrate, sizeof(*p));
467     return OMX_ErrorNone;
468 }
469 
SetParamVideoBitrate(OMX_PTR pStructure)470 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) {
471     OMX_ERRORTYPE ret;
472     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
473     CHECK_TYPE_HEADER(p);
474     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
475     CHECK_SET_PARAM_STATE();
476     OMX_U32 index = p->nPortIndex;
477     PortVideo *port = NULL;
478     // This disables other type of bitrate control mechanism
479     // TODO: check if it is desired
480 
481     // TODO: can we override  mParamBitrate.nPortIndex (See SetPortBitrateParam)
482     mParamBitrate.eControlRate = p->eControlRate;
483     mParamBitrate.nTargetBitrate = p->nTargetBitrate;
484 
485     port = static_cast<PortVideo *>(ports[index]);
486     ret = port->SetPortBitrateParam(p, false);
487     return OMX_ErrorNone;
488 }
489 
GetIntelPrivateInfo(OMX_PTR pStructure)490 OMX_ERRORTYPE OMXVideoEncoderBase::GetIntelPrivateInfo(OMX_PTR pStructure) {
491     OMX_ERRORTYPE ret;
492     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
493 
494     CHECK_TYPE_HEADER(p);
495     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
496     memcpy(p, &mConfigPriInfo, sizeof(*p));
497     return OMX_ErrorNone;
498 }
499 
SetIntelPrivateInfo(OMX_PTR pStructure)500 OMX_ERRORTYPE OMXVideoEncoderBase::SetIntelPrivateInfo(OMX_PTR pStructure) {
501     OMX_ERRORTYPE ret;
502     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
503     CHECK_TYPE_HEADER(p);
504     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
505 
506     // OMX_VIDEO_CONFIG_PRI_INFOTYPE is static parameter?
507     CHECK_SET_PARAM_STATE();
508 
509     // TODO: can we override  mConfigPriInfo.nPortIndex (See SetPortPrivateInfoParam)
510 
511     if(p->nHolder != NULL) {
512         // TODO: do we need to free nHolder?
513         if (mConfigPriInfo.nHolder) {
514             free(mConfigPriInfo.nHolder);
515         }
516         mConfigPriInfo.nCapacity = p->nCapacity;
517         // TODO: nCapacity is in 8-bit unit or 32-bit unit?
518         // TODO: check memory allocation
519         mConfigPriInfo.nHolder = (OMX_PTR)malloc(sizeof(OMX_U32) * p->nCapacity);
520         memcpy(mConfigPriInfo.nHolder, p->nHolder, sizeof(OMX_U32) * p->nCapacity);
521     } else {
522         mConfigPriInfo.nCapacity = 0;
523         mConfigPriInfo.nHolder = NULL;
524     }
525 
526     return OMX_ErrorNone;
527 }
528 
GetConfigIntelBitrate(OMX_PTR pStructure)529 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) {
530     OMX_ERRORTYPE ret;
531     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
532 
533     CHECK_TYPE_HEADER(p);
534     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
535     memcpy(p, &mConfigIntelBitrate, sizeof(*p));
536     return OMX_ErrorNone;
537 }
538 
SetConfigIntelBitrate(OMX_PTR pStructure)539 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) {
540     OMX_ERRORTYPE ret;
541     Encode_Status retStatus = ENCODE_SUCCESS;
542     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
543         LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
544         return OMX_ErrorUnsupportedIndex;
545     }
546     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
547     CHECK_TYPE_HEADER(p);
548     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
549 
550     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
551     mConfigIntelBitrate = *p;
552 
553     // return OMX_ErrorNone if not in Executing state
554     // TODO: return OMX_ErrorIncorrectStateOperation?
555     CHECK_SET_CONFIG_STATE();
556 
557     VideoConfigBitRate configBitRate;
558     configBitRate.rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
559     configBitRate.rcParams.initQP = mConfigIntelBitrate.nInitialQP;
560     configBitRate.rcParams.minQP = mConfigIntelBitrate.nMinQP;
561     configBitRate.rcParams.maxQP = mConfigIntelBitrate.nMaxQP;
562     configBitRate.rcParams.I_minQP = 0;
563     configBitRate.rcParams.I_maxQP = 0;
564     configBitRate.rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
565     configBitRate.rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
566     configBitRate.rcParams.enableIntraFrameQPControl = 0;
567     configBitRate.rcParams.temporalFrameRate = mConfigIntelBitrate.nFrameRate;
568     configBitRate.rcParams.temporalID = mConfigIntelBitrate.nTemporalID;
569     retStatus = mVideoEncoder->setConfig(&configBitRate);
570     if(retStatus != ENCODE_SUCCESS) {
571         LOGW("failed to set IntelBitrate");
572     }
573     return OMX_ErrorNone;
574 }
575 
GetConfigIntelAIR(OMX_PTR pStructure)576 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) {
577     OMX_ERRORTYPE ret;
578     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
579 
580     CHECK_TYPE_HEADER(p);
581     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
582     memcpy(p, &mConfigIntelAir, sizeof(*p));
583     return OMX_ErrorNone;
584 }
585 
SetConfigIntelAIR(OMX_PTR pStructure)586 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) {
587     OMX_ERRORTYPE ret;
588     Encode_Status retStatus = ENCODE_SUCCESS;
589 
590     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
591     CHECK_TYPE_HEADER(p);
592     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
593 
594     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
595     mConfigIntelAir = *p;
596 
597     // return OMX_ErrorNone if not in Executing state
598     // TODO: return OMX_ErrorIncorrectStateOperation?
599     CHECK_SET_CONFIG_STATE();
600 
601     VideoConfigAIR configAIR;
602     VideoConfigIntraRefreshType configIntraRefreshType;
603     if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
604         configAIR.airParams.airAuto = mConfigIntelAir.bAirAuto;
605         configAIR.airParams.airMBs = mConfigIntelAir.nAirMBs;
606         configAIR.airParams.airThreshold = mConfigIntelAir.nAirThreshold;
607         configIntraRefreshType.refreshType = VIDEO_ENC_AIR;
608     } else {
609         configIntraRefreshType.refreshType = VIDEO_ENC_NONIR;
610     }
611 
612     retStatus = mVideoEncoder->setConfig(&configAIR);
613     if(retStatus != ENCODE_SUCCESS) {
614         LOGW("Failed to set AIR config");
615     }
616 
617     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
618     if(retStatus != ENCODE_SUCCESS) {
619         LOGW("Failed to set refresh config");
620     }
621     return OMX_ErrorNone;
622 }
623 
GetParamVideoIntraRefresh(OMX_PTR pStructure)624 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoIntraRefresh(OMX_PTR pStructure) {
625     OMX_ERRORTYPE ret;
626     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
627 
628     CHECK_TYPE_HEADER(p);
629     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
630     memcpy(p, &mParamVideoRefresh, sizeof(*p));
631     return OMX_ErrorNone;
632 }
633 
SetParamVideoIntraRefresh(OMX_PTR pStructure)634 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoIntraRefresh(OMX_PTR pStructure) {
635     OMX_ERRORTYPE ret;
636     Encode_Status retStatus = ENCODE_SUCCESS;
637 
638     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
639     CHECK_TYPE_HEADER(p);
640     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
641 
642     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
643     mParamVideoRefresh = *p;
644 
645     // return OMX_ErrorNone if not in Executing state
646     // TODO: return OMX_ErrorIncorrectStateOperation?
647     CHECK_SET_PARAM_STATE();
648 
649     VideoConfigIntraRefreshType configIntraRefreshType;
650     configIntraRefreshType.refreshType = (VideoIntraRefreshType)(mParamVideoRefresh.eRefreshMode + 1);
651     if(configIntraRefreshType.refreshType == VIDEO_ENC_CIR){
652      VideoConfigCIR configCIR;
653         VideoConfigIntraRefreshType configIntraRefreshType;
654         configCIR.cirParams.cir_num_mbs = mParamVideoRefresh.nCirMBs;
655         configIntraRefreshType.refreshType = VIDEO_ENC_CIR;
656 
657         retStatus = mVideoEncoder->setConfig(&configCIR);
658         if(retStatus != ENCODE_SUCCESS) {
659             LOGW("Failed to set CIR config");
660         }
661     }else{
662         VideoConfigAIR configAIR;
663 
664         configAIR.airParams.airMBs = mParamVideoRefresh.nAirMBs;
665         configAIR.airParams.airThreshold = mParamVideoRefresh.nAirRef;
666 
667         retStatus = mVideoEncoder->setConfig(&configAIR);
668         if(retStatus != ENCODE_SUCCESS) {
669             LOGW("Failed to set AIR config");
670         }
671 
672     }
673 
674     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
675     if(retStatus != ENCODE_SUCCESS) {
676         LOGW("Failed to set refresh config");
677     }
678 
679     return OMX_ErrorNone;
680 }
681 
GetConfigVideoFramerate(OMX_PTR pStructure)682 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) {
683     OMX_ERRORTYPE ret;
684     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
685 
686     CHECK_TYPE_HEADER(p);
687     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
688     memcpy(p, &mConfigFramerate, sizeof(*p));
689     return OMX_ErrorNone;
690 }
691 
SetConfigVideoFramerate(OMX_PTR pStructure)692 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) {
693     OMX_ERRORTYPE ret;
694     Encode_Status retStatus = ENCODE_SUCCESS;
695     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
696         LOGE("SetConfigVideoFramerate failed. Feature is disabled.");
697         return OMX_ErrorUnsupportedIndex;
698     }
699     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
700     CHECK_TYPE_HEADER(p);
701     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
702 
703     // set in either Loaded state  (ComponentSetParam) or Executing state (ComponentSetConfig)
704     mConfigFramerate = *p;
705 
706     // return OMX_ErrorNone if not in Executing state
707     // TODO, return OMX_ErrorIncorrectStateOperation?
708     CHECK_SET_CONFIG_STATE();
709 
710     VideoConfigFrameRate framerate;
711     framerate.frameRate.frameRateDenom = 1;
712     framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate >> 16;
713     retStatus = mVideoEncoder->setConfig(&framerate);
714     if(retStatus != ENCODE_SUCCESS) {
715         LOGW("Failed to set frame rate config");
716     }
717     return OMX_ErrorNone;
718 }
719 
GetConfigVideoIntraVOPRefresh(OMX_PTR)720 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR) {
721     LOGW("GetConfigVideoIntraVOPRefresh is not supported.");
722     return OMX_ErrorUnsupportedSetting;
723 }
724 
SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure)725 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) {
726     OMX_ERRORTYPE ret;
727     Encode_Status retStatus = ENCODE_SUCCESS;
728     OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure;
729     CHECK_TYPE_HEADER(p);
730     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
731 
732     // return OMX_ErrorNone if not in Executing state
733     // TODO: return OMX_ErrorIncorrectStateOperation?
734     CHECK_SET_CONFIG_STATE();
735 
736     if(p->IntraRefreshVOP == OMX_TRUE) {
737         VideoParamConfigSet configIDRRequest;
738         configIDRRequest.type = VideoConfigTypeIDRRequest;
739         retStatus = mVideoEncoder->setConfig(&configIDRRequest);
740         if(retStatus != ENCODE_SUCCESS) {
741             LOGW("Failed to set refresh config");
742         }
743     }
744 
745     return OMX_ErrorNone;
746 }
747 
GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure)748 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
749 
750     OMX_ERRORTYPE ret;
751     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
752 
753     CHECK_TYPE_HEADER(p);
754     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
755     memcpy(p, &mParamIntelAdaptiveSliceControl, sizeof(*p));
756 
757     return OMX_ErrorNone;
758 }
759 
SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure)760 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
761 
762     OMX_ERRORTYPE ret;
763     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) {
764         LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled.");
765         return OMX_ErrorUnsupportedIndex;
766     }
767     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
768     CHECK_TYPE_HEADER(p);
769     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
770 
771     // set only in Loaded state (ComponentSetParam)
772     CHECK_SET_PARAM_STATE();
773 
774     mParamIntelAdaptiveSliceControl = *p;
775 
776     return OMX_ErrorNone;
777 }
778 
779 /*
780 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
781     OMX_ERRORTYPE ret;
782     OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
783 
784     CHECK_TYPE_HEADER(p);
785     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
786 
787     // assign values instead of memory coping to avoid nProfileIndex being overridden
788     p->eProfile = mParamProfileLevel.eProfile;
789     p->eLevel = mParamProfileLevel.eLevel;
790 
791     return OMX_ErrorNone;
792 }
793 
794 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
795     LOGW("SetParamVideoProfileLevelQuerySupported is not supported.");
796     return OMX_ErrorUnsupportedSetting;
797 }
798 */
799 
GetStoreMetaDataInBuffers(OMX_PTR pStructure)800 OMX_ERRORTYPE OMXVideoEncoderBase::GetStoreMetaDataInBuffers(OMX_PTR pStructure) {
801     OMX_ERRORTYPE ret;
802     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
803 
804     CHECK_TYPE_HEADER(p);
805     CHECK_PORT_INDEX(p, INPORT_INDEX);
806 
807     p->bStoreMetaData = mStoreMetaDataInBuffers;
808 
809     return OMX_ErrorNone;
810 };
SetStoreMetaDataInBuffers(OMX_PTR pStructure)811 OMX_ERRORTYPE OMXVideoEncoderBase::SetStoreMetaDataInBuffers(OMX_PTR pStructure) {
812     OMX_ERRORTYPE ret;
813     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
814     VideoParamsStoreMetaDataInBuffers StoreMetaDataInBuffers;
815     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
816     PortVideo *output_port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
817     uint32_t maxSize = 0;
818 
819     CHECK_TYPE_HEADER(p);
820     CHECK_PORT_INDEX(p, INPORT_INDEX);
821 
822     LOGD("SetStoreMetaDataInBuffers (enabled = %x)", p->bStoreMetaData);
823     if(mStoreMetaDataInBuffers == p->bStoreMetaData)
824         return OMX_ErrorNone;
825 
826     StoreMetaDataInBuffers.isEnabled = p->bStoreMetaData;
827     if (mVideoEncoder->setParameters(&StoreMetaDataInBuffers) != ENCODE_SUCCESS)
828         return OMX_ErrorNotReady;
829 
830     mStoreMetaDataInBuffers = p->bStoreMetaData;
831 
832     if(mStoreMetaDataInBuffers){
833         // for input port buffer
834         OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput;
835         const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get;
836 
837         paramPortDefinitionInput_get = port->GetPortDefinition();
838         paramPortDefinitionInput = (OMX_PARAM_PORTDEFINITIONTYPE *)paramPortDefinitionInput_get;
839         paramPortDefinitionInput->nBufferSize = IntelMetadataBuffer::GetMaxBufferSize();
840     }
841     else
842     {
843         const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get;
844 
845         paramPortDefinitionInput_get = port->GetPortDefinition();
846         port->SetPortDefinition(paramPortDefinitionInput_get, true);
847     }
848 
849     LOGD("SetStoreMetaDataInBuffers success");
850     return OMX_ErrorNone;
851 };
852 
GetSyncEncoding(OMX_PTR pStructure)853 OMX_ERRORTYPE OMXVideoEncoderBase::GetSyncEncoding(OMX_PTR pStructure) {
854     OMX_BOOL* syncEncoding = static_cast<OMX_BOOL*>(pStructure);
855 
856     *syncEncoding = mSyncEncoding;
857 
858     return OMX_ErrorNone;
859 };
860 
SetSyncEncoding(OMX_PTR pStructure)861 OMX_ERRORTYPE OMXVideoEncoderBase::SetSyncEncoding(OMX_PTR pStructure) {
862     CHECK_SET_PARAM_STATE();
863 
864     mSyncEncoding = *(static_cast<OMX_BOOL*>(pStructure));
865 
866     LOGD("SetSyncEncoding %d", mSyncEncoding);
867 
868     return OMX_ErrorNone;
869 };
870 
GetPrependSPSPPS(OMX_PTR)871 OMX_ERRORTYPE OMXVideoEncoderBase::GetPrependSPSPPS(OMX_PTR) {
872     return OMX_ErrorNone;
873 };
874 
SetPrependSPSPPS(OMX_PTR)875 OMX_ERRORTYPE OMXVideoEncoderBase::SetPrependSPSPPS(OMX_PTR) {
876     LOGD("SetPrependSPSPPS success");
877     return OMX_ErrorNone;
878 };
879 
GetTemporalLayer(OMX_PTR pStructure)880 OMX_ERRORTYPE OMXVideoEncoderBase::GetTemporalLayer(OMX_PTR pStructure) {
881     OMX_ERRORTYPE ret;
882     OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER* p = static_cast<OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER*>(pStructure);
883 
884     CHECK_TYPE_HEADER(p);
885     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
886     memcpy(p, &mTemporalLayer, sizeof(*p));
887     return OMX_ErrorNone;
888 }
889 
SetTemporalLayer(OMX_PTR pStructure)890 OMX_ERRORTYPE OMXVideoEncoderBase::SetTemporalLayer(OMX_PTR pStructure) {
891     OMX_ERRORTYPE ret;
892     OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *p = (OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *)pStructure;
893     VideoParamsTemporalLayer TemporalLayer;
894     OMX_U32 i;
895 
896     CHECK_TYPE_HEADER(p);
897     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
898 
899     LOGE("SetTemporalLayer (enabled = %d)", p->nNumberOfTemporalLayer);
900 
901     TemporalLayer.numberOfLayer = p->nNumberOfTemporalLayer;
902     TemporalLayer.nPeriodicity = p->nPeriodicity;
903     for(i=0;i<p->nPeriodicity;i++)
904         TemporalLayer.nLayerID[i] = p->nLayerID[i];
905 
906     if (mVideoEncoder->setParameters(&TemporalLayer) != ENCODE_SUCCESS)
907         return OMX_ErrorNotReady;
908 
909     LOGE("SetTemporalLayer success");
910     return OMX_ErrorNone;
911 }
912 
GetBlackFramePointer(OMX_PTR pStructure)913 OMX_ERRORTYPE OMXVideoEncoderBase::GetBlackFramePointer(OMX_PTR pStructure) {
914     OMX_ERRORTYPE ret;
915     OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *p = (OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *)pStructure;
916 
917     CHECK_TYPE_HEADER(p);
918     CHECK_PORT_INDEX(p, INPORT_INDEX);
919 
920     PortVideo *port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]);
921     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = port_in->GetPortDefinition();
922     OMX_U32 width = paramPortDefinitionInput->format.video.nFrameWidth;
923     OMX_U32 height = paramPortDefinitionInput->format.video.nFrameHeight;
924     OMX_U32 lumaSize = width * height;
925     OMX_U32 bufferSize = width * height * 3 / 2;
926 
927     if(mBlackFramePointer) {
928         free(mBlackFramePointer);
929         mBlackFramePointer = NULL;
930     } else {
931         mBlackFramePointer = (OMX_PTR)memalign(4096, bufferSize); // align to page size
932         if(!mBlackFramePointer) {
933             return OMX_ErrorInsufficientResources;
934         }
935         memset(mBlackFramePointer, 0x0, lumaSize);
936         memset((OMX_PTR)((uint64_t)mBlackFramePointer + lumaSize), 0x80, lumaSize / 2);
937         p->nFramePointer = (OMX_U32)mBlackFramePointer;
938     }
939     return OMX_ErrorNone;
940 }
941 
SetBlackFramePointer(OMX_PTR)942 OMX_ERRORTYPE OMXVideoEncoderBase::SetBlackFramePointer(OMX_PTR) {
943     return OMX_ErrorUnsupportedSetting;
944 }
945 
GetConfigVideoBitrate(OMX_PTR pStructure)946 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoBitrate(OMX_PTR pStructure) {
947 
948     OMX_ERRORTYPE ret;
949     OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
950 
951     CHECK_TYPE_HEADER(p);
952     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
953     memcpy(p, &mConfigBitrate, sizeof(*p));
954     return OMX_ErrorNone;
955 }
SetConfigVideoBitrate(OMX_PTR pStructure)956 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoBitrate(OMX_PTR pStructure){
957     OMX_ERRORTYPE ret;
958     Encode_Status retStatus = ENCODE_SUCCESS;
959     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
960         LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
961         return OMX_ErrorUnsupportedIndex;
962     }
963     OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
964     CHECK_TYPE_HEADER(p);
965     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
966 
967     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
968     mConfigBitrate = *p;
969 
970     // return OMX_ErrorNone if not in Executing state
971     // TODO: return OMX_ErrorIncorrectStateOperation?
972     // CHECK_SET_CONFIG_STATE();
973 
974     VideoConfigBitRate configBitRate;
975     configBitRate.rcParams.bitRate = mConfigBitrate.nEncodeBitrate;
976     configBitRate.rcParams.temporalID = 0;
977     retStatus = mVideoEncoder->setConfig(&configBitRate);
978     if(retStatus != ENCODE_SUCCESS) {
979         LOGW("failed to set IntelBitrate");
980     }
981     return OMX_ErrorNone;
982 }
983