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 #include <media/stagefright/foundation/AUtils.h>
24 
25 static const char *RAW_MIME_TYPE = "video/raw";
26 
OMXVideoEncoderBase()27 OMXVideoEncoderBase::OMXVideoEncoderBase()
28     :mVideoEncoder(NULL)
29     ,mEncoderParams(NULL)
30     ,mFrameInputCount(0)
31     ,mFrameOutputCount(0)
32     ,mFirstFrame(OMX_TRUE)
33     ,mFrameRetrieved(OMX_TRUE)
34     ,mStoreMetaDataInBuffers(OMX_FALSE)
35     ,mSyncEncoding(OMX_TRUE)
36     ,mOmxLogLevel(0)
37     ,mBlackFramePointer(NULL) {
38     mEncoderParams = new VideoParamsCommon();
39     if (!mEncoderParams) LOGE("OMX_ErrorInsufficientResources");
40 
41     char logLevelProp[128];
42     if (property_get("omxenc.debug", logLevelProp, NULL)) {
43         mOmxLogLevel = atoi(logLevelProp);
44         LOGD("Debug level is %d", mOmxLogLevel);
45     }
46 
47     LOGV("OMXVideoEncoderBase::OMXVideoEncoderBase end");
48 }
49 
~OMXVideoEncoderBase()50 OMXVideoEncoderBase::~OMXVideoEncoderBase() {
51 
52     // destroy ports
53     if (this->ports) {
54         if (this->ports[INPORT_INDEX]) {
55             delete this->ports[INPORT_INDEX];
56             this->ports[INPORT_INDEX] = NULL;
57         }
58 
59         if (this->ports[OUTPORT_INDEX]) {
60             delete this->ports[OUTPORT_INDEX];
61             this->ports[OUTPORT_INDEX] = NULL;
62         }
63     }
64 
65     if (mBlackFramePointer) {
66         free(mBlackFramePointer);
67         mBlackFramePointer = NULL;
68     }
69     // Release video encoder object
70     if(mVideoEncoder) {
71         releaseVideoEncoder(mVideoEncoder);
72         mVideoEncoder = NULL;
73     }
74 
75     if(mEncoderParams) {
76         delete mEncoderParams;
77         mEncoderParams = NULL;
78     }
79 
80 }
81 
InitInputPort(void)82 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) {
83     this->ports[INPORT_INDEX] = new PortVideo;
84     if (this->ports[INPORT_INDEX] == NULL) {
85         return OMX_ErrorInsufficientResources;
86     }
87 
88     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
89 
90     // OMX_PARAM_PORTDEFINITIONTYPE
91     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
92     memset(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
93     SetTypeHeader(&paramPortDefinitionInput, sizeof(paramPortDefinitionInput));
94     paramPortDefinitionInput.nPortIndex = INPORT_INDEX;
95     paramPortDefinitionInput.eDir = OMX_DirInput;
96     paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
97     paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
98     paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE;
99     paramPortDefinitionInput.bEnabled = OMX_TRUE;
100     paramPortDefinitionInput.bPopulated = OMX_FALSE;
101     paramPortDefinitionInput.eDomain = OMX_PortDomainVideo;
102     paramPortDefinitionInput.format.video.cMIMEType = (OMX_STRING)RAW_MIME_TYPE;
103     paramPortDefinitionInput.format.video.pNativeRender = NULL;
104     paramPortDefinitionInput.format.video.nFrameWidth = 176;
105     paramPortDefinitionInput.format.video.nFrameHeight = 144;
106     paramPortDefinitionInput.format.video.nStride = 0;
107     paramPortDefinitionInput.format.video.nSliceHeight = 0;
108     paramPortDefinitionInput.format.video.nBitrate = 64000;
109     paramPortDefinitionInput.format.video.xFramerate = 15 << 16;
110     paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE;
111     paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
112     paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
113     paramPortDefinitionInput.format.video.pNativeWindow = NULL;
114     paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE;
115     paramPortDefinitionInput.nBufferAlignment = 0;
116 
117     // Nothing specific to initialize input port.
118     InitInputPortFormatSpecific(&paramPortDefinitionInput);
119 
120     port->SetPortDefinition(&paramPortDefinitionInput, true);
121 
122     // Set port buffer 4k aligned
123     port->SetMemAlignment(4096);
124 
125     // OMX_VIDEO_PARAM_PORTFORMATTYPE
126     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
127     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
128     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
129     paramPortFormat.nPortIndex = INPORT_INDEX;
130     paramPortFormat.nIndex = 0;
131     paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat;
132     paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat;
133     paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate;
134 
135     port->SetPortVideoParam(&paramPortFormat, true);
136 
137     return OMX_ErrorNone;
138 }
139 
140 
InitOutputPort(void)141 OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) {
142     this->ports[OUTPORT_INDEX] = new PortVideo;
143     if (this->ports[OUTPORT_INDEX] == NULL) {
144         return OMX_ErrorInsufficientResources;
145     }
146 
147     PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
148 
149     // OMX_VIDEO_PARAM_BITRATETYPE
150     memset(&mParamBitrate, 0, sizeof(mParamBitrate));
151     SetTypeHeader(&mParamBitrate, sizeof(mParamBitrate));
152     mParamBitrate.nPortIndex = OUTPORT_INDEX;
153     mParamBitrate.eControlRate = OMX_Video_ControlRateVariable;
154     mParamBitrate.nTargetBitrate = 192000; // to be overridden
155 
156     // OMX_VIDEO_CONFIG_PRI_INFOTYPE
157     memset(&mConfigPriInfo, 0, sizeof(mConfigPriInfo));
158     SetTypeHeader(&mConfigPriInfo, sizeof(mConfigPriInfo));
159     mConfigPriInfo.nPortIndex = OUTPORT_INDEX;
160     mConfigPriInfo.nCapacity = 0;
161     mConfigPriInfo.nHolder = NULL;
162 
163     // OMX_VIDEO_CONFIG_INTEL_BITRATETYPE
164     memset(&mConfigIntelBitrate, 0, sizeof(mConfigIntelBitrate));
165     SetTypeHeader(&mConfigIntelBitrate, sizeof(mConfigIntelBitrate));
166     mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX;
167     mConfigIntelBitrate.nMaxEncodeBitrate = 0; // Maximum bitrate
168     mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95%
169     mConfigIntelBitrate.nWindowSize = 0; // Window size in milliseconds allowed for bitrate to reach target
170     mConfigIntelBitrate.nInitialQP = 0;  // Initial QP for I frames
171     mConfigIntelBitrate.nMinQP = 0;
172     mConfigIntelBitrate.nMaxQP = 0;
173     mConfigIntelBitrate.nFrameRate = 0;
174     mConfigIntelBitrate.nTemporalID = 0;
175 
176     // OMX_VIDEO_CONFIG_BITRATETYPE
177     memset(&mConfigBitrate, 0, sizeof(mConfigBitrate));
178     SetTypeHeader(&mConfigBitrate, sizeof(mConfigBitrate));
179     mConfigBitrate.nPortIndex = OUTPORT_INDEX;
180     mConfigBitrate.nEncodeBitrate = 0; // Maximum bitrate
181 
182     // OMX_VIDEO_CONFIG_INTEL_AIR
183     memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir));
184     SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir));
185     mConfigIntelAir.nPortIndex = OUTPORT_INDEX;
186     mConfigIntelAir.bAirEnable = OMX_FALSE;
187     mConfigIntelAir.bAirAuto = OMX_FALSE;
188     mConfigIntelAir.nAirMBs = 0;
189     mConfigIntelAir.nAirThreshold = 0;
190 
191     // OMX_VIDEO_CONFIG_INTEL_AIR
192     memset(&mParamVideoRefresh, 0, sizeof(mParamVideoRefresh));
193     SetTypeHeader(&mParamVideoRefresh, sizeof(mParamVideoRefresh));
194     mParamVideoRefresh.nPortIndex = OUTPORT_INDEX;
195     mParamVideoRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshAdaptive;
196     mParamVideoRefresh.nAirMBs = 0;
197     mParamVideoRefresh.nAirRef = 0;
198     mParamVideoRefresh.nCirMBs = 0;
199 
200     // OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESH
201     memset(&mConfigAndroidIntraRefresh, 0, sizeof(mConfigAndroidIntraRefresh));
202     SetTypeHeader(&mConfigAndroidIntraRefresh, sizeof(mConfigAndroidIntraRefresh));
203     mConfigAndroidIntraRefresh.nPortIndex = OUTPORT_INDEX;
204     mConfigAndroidIntraRefresh.nRefreshPeriod = 0; // default feature closed
205 
206     // OMX_CONFIG_FRAMERATETYPE
207     memset(&mConfigFramerate, 0, sizeof(mConfigFramerate));
208     SetTypeHeader(&mConfigFramerate, sizeof(mConfigFramerate));
209     mConfigFramerate.nPortIndex = OUTPORT_INDEX;
210     mConfigFramerate.xEncodeFramerate =  0; // Q16 format
211 
212     // OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL
213     memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl));
214     SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl));
215     mParamIntelAdaptiveSliceControl.nPortIndex = OUTPORT_INDEX;
216     mParamIntelAdaptiveSliceControl.bEnable = OMX_FALSE;
217     mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5;
218     mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8;
219     mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200;
220 
221     // OMX_VIDEO_PARAM_PROFILELEVELTYPE
222     memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel));
223     SetTypeHeader(&mParamProfileLevel, sizeof(mParamProfileLevel));
224     mParamProfileLevel.nPortIndex = OUTPORT_INDEX;
225     mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden
226     mParamProfileLevel.eLevel = 0; // undefined level, to be overridden
227 
228     // OMX_PARAM_PORTDEFINITIONTYPE
229     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput;
230     memset(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
231     SetTypeHeader(&paramPortDefinitionOutput, sizeof(paramPortDefinitionOutput));
232     paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX;
233     paramPortDefinitionOutput.eDir = OMX_DirOutput;
234     paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; // to be overridden
235     paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
236     paramPortDefinitionOutput.nBufferSize = OUTPORT_BUFFER_SIZE; // to be overridden
237     paramPortDefinitionOutput.bEnabled = OMX_TRUE;
238     paramPortDefinitionOutput.bPopulated = OMX_FALSE;
239     paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo;
240     paramPortDefinitionOutput.format.video.cMIMEType = NULL; // to be overridden
241     paramPortDefinitionOutput.format.video.pNativeRender = NULL;
242     paramPortDefinitionOutput.format.video.nFrameWidth = 176;
243     paramPortDefinitionOutput.format.video.nFrameHeight = 144;
244     paramPortDefinitionOutput.format.video.nStride = 176;
245     paramPortDefinitionOutput.format.video.nSliceHeight = 144;
246     paramPortDefinitionOutput.format.video.nBitrate = 64000;
247     paramPortDefinitionOutput.format.video.xFramerate = 15 << 16;
248     paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE;
249     paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden
250     paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatUnused;
251     paramPortDefinitionOutput.format.video.pNativeWindow = NULL;
252     paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE;
253     paramPortDefinitionOutput.nBufferAlignment = 0;
254 
255     InitOutputPortFormatSpecific(&paramPortDefinitionOutput);
256 
257     port->SetPortDefinition(&paramPortDefinitionOutput, true);
258     port->SetPortBitrateParam(&mParamBitrate, true);
259 
260     // OMX_VIDEO_PARAM_PORTFORMATTYPE
261     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
262     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
263     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
264     paramPortFormat.nPortIndex = OUTPORT_INDEX;
265     paramPortFormat.nIndex = 0;
266     paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat;
267     paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat;
268     paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate;
269 
270     port->SetPortVideoParam(&paramPortFormat, true);
271     return OMX_ErrorNone;
272 }
273 
InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *)274 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
275     // no format specific to initialize input
276     return OMX_ErrorNone;
277 }
278 
SetVideoEncoderParam()279 OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() {
280 
281     Encode_Status ret = ENCODE_SUCCESS;
282     PortVideo *port_in = NULL;
283     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = NULL;
284     LOGV("OMXVideoEncoderBase::SetVideoEncoderParam called\n");
285 
286     port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]);
287     paramPortDefinitionInput = port_in->GetPortDefinition();
288     mEncoderParams->resolution.height = paramPortDefinitionInput->format.video.nFrameHeight;
289     mEncoderParams->resolution.width = paramPortDefinitionInput->format.video.nFrameWidth;
290 
291     mEncoderParams->frameRate.frameRateDenom = 1;
292     if(mConfigFramerate.xEncodeFramerate != 0) {
293         mEncoderParams->frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate;
294     } else {
295         mEncoderParams->frameRate.frameRateNum = paramPortDefinitionInput->format.video.xFramerate >> 16;
296         mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16;
297     }
298 
299     if(mEncoderParams->intraPeriod == 0) {
300         OMX_U32 intraPeriod = mEncoderParams->frameRate.frameRateNum / 2;
301         mEncoderParams->intraPeriod = (intraPeriod < 15) ? 15 : intraPeriod;   // Limit intra frame period to ensure video quality for low bitrate application.
302     }
303 
304     if (paramPortDefinitionInput->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque)
305         mEncoderParams->rawFormat = RAW_FORMAT_OPAQUE;
306     else
307         mEncoderParams->rawFormat = RAW_FORMAT_NV12;
308 
309     LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom);
310     LOGV("frameRate.frameRateNum = %d\n", mEncoderParams->frameRate.frameRateNum);
311     LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod);
312     mEncoderParams->rcParams.initQP = mConfigIntelBitrate.nInitialQP;
313     mEncoderParams->rcParams.minQP = mConfigIntelBitrate.nMinQP;
314     mEncoderParams->rcParams.maxQP = 0;
315     mEncoderParams->rcParams.I_minQP = 0;
316     mEncoderParams->rcParams.I_maxQP = 0;
317     mEncoderParams->rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
318     mEncoderParams->rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
319     mEncoderParams->rcParams.enableIntraFrameQPControl = 0;
320 
321     mEncoderParams->rcParams.bitRate = mParamBitrate.nTargetBitrate;
322     if ((mParamBitrate.eControlRate == OMX_Video_ControlRateConstant )||
323             (mParamBitrate.eControlRate == OMX_Video_ControlRateConstantSkipFrames)) {
324         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateConstant", __func__);
325         mEncoderParams->rcMode = RATE_CONTROL_CBR;
326     } else if ((mParamBitrate.eControlRate == OMX_Video_ControlRateVariable) ||
327             (mParamBitrate.eControlRate == OMX_Video_ControlRateVariableSkipFrames)) {
328         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVariable", __func__);
329         mEncoderParams->rcMode = RATE_CONTROL_VBR;
330     } else if (mParamBitrate.eControlRate == (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) {
331         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode ", __func__);
332         mEncoderParams->rcMode = RATE_CONTROL_VCM;
333         if(mConfigIntelBitrate.nMaxEncodeBitrate >0)
334             mEncoderParams->rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
335         if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
336             mEncoderParams->airParams.airAuto = mConfigIntelAir.bAirAuto;
337             mEncoderParams->airParams.airMBs = mConfigIntelAir.nAirMBs;
338             mEncoderParams->airParams.airThreshold = mConfigIntelAir.nAirThreshold;
339             mEncoderParams->refreshType = VIDEO_ENC_AIR;
340         } else {
341             mEncoderParams->refreshType = VIDEO_ENC_NONIR;
342         }
343         LOGV("refreshType = %d\n", mEncoderParams->refreshType);
344     } else {
345         mEncoderParams->rcMode = RATE_CONTROL_NONE;
346     }
347 
348     ret = mVideoEncoder->setParameters(mEncoderParams);
349     CHECK_ENCODE_STATUS("setParameters");
350     return OMX_ErrorNone;
351 }
352 
ProcessorInit(void)353 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) {
354     OMX_ERRORTYPE ret = OMX_ErrorNone;
355     ret = SetVideoEncoderParam();
356     CHECK_STATUS("SetVideoEncoderParam");
357 
358     Encode_Status status = mVideoEncoder->start();
359     if (status != ENCODE_SUCCESS) {
360         LOGE("Start failed, status = 0x%08x\n", status);
361         return OMX_ErrorUndefined;
362     }
363 
364     return OMX_ErrorNone;
365 }
366 
ProcessorDeinit(void)367 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) {
368     if(mVideoEncoder) {
369         mVideoEncoder->stop();
370     }
371 
372     return OMX_ErrorNone;
373 }
374 
ProcessorStop(void)375 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) {
376 
377     this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
378     return OMX_ErrorNone;
379 }
ProcessorProcess(OMX_BUFFERHEADERTYPE **,buffer_retain_t *,OMX_U32)380 OMX_ERRORTYPE OMXVideoEncoderBase:: ProcessorProcess(
381     OMX_BUFFERHEADERTYPE **,
382     buffer_retain_t *,
383     OMX_U32) {
384 
385     LOGV("OMXVideoEncoderBase:: ProcessorProcess \n");
386     return OMX_ErrorNone;
387 }
388 
ProcessorFlush(OMX_U32 portIndex)389 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) {
390     LOGV("OMXVideoEncoderBase::ProcessorFlush\n");
391     if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
392         this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
393         mVideoEncoder->flush();
394     }
395     return OMX_ErrorNone;
396 }
397 
BuildHandlerList(void)398 OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) {
399     OMXComponentCodecBase::BuildHandlerList();
400     AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat);
401     AddHandler(OMX_IndexParamVideoBitrate, GetParamVideoBitrate, SetParamVideoBitrate);
402     AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo);
403     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate);
404     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR);
405     AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoIntraRefresh, GetParamVideoIntraRefresh, SetParamVideoIntraRefresh);
406     AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate);
407     AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh);
408     //AddHandler(OMX_IndexParamIntelAdaptiveSliceControl, GetParamIntelAdaptiveSliceControl, SetParamIntelAdaptiveSliceControl);
409     //AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported);
410     AddHandler((OMX_INDEXTYPE)OMX_IndexStoreMetaDataInBuffers, GetStoreMetaDataInBuffers, SetStoreMetaDataInBuffers);
411     AddHandler((OMX_INDEXTYPE)OMX_IndexExtSyncEncoding, GetSyncEncoding, SetSyncEncoding);
412     AddHandler((OMX_INDEXTYPE)OMX_IndexExtPrependSPSPPS, GetPrependSPSPPS, SetPrependSPSPPS);
413     AddHandler((OMX_INDEXTYPE)OMX_IndexExtTemporalLayer, GetTemporalLayer,SetTemporalLayer);
414     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoBitrate, GetConfigVideoBitrate, SetConfigVideoBitrate);
415     AddHandler((OMX_INDEXTYPE)OMX_IndexExtRequestBlackFramePointer, GetBlackFramePointer, GetBlackFramePointer);
416     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, GetConfigAndroidIntraRefresh, SetConfigAndroidIntraRefresh);
417     return OMX_ErrorNone;
418 }
419 
GetParamVideoPortFormat(OMX_PTR pStructure)420 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) {
421     OMX_ERRORTYPE ret;
422     OMX_U32 index;
423     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
424 
425     CHECK_TYPE_HEADER(p);
426     CHECK_PORT_INDEX_RANGE(p);
427     CHECK_ENUMERATION_RANGE(p->nIndex, 2);
428 
429     PortVideo *port = NULL;
430     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
431     index = p->nIndex;
432     memcpy(p, port->GetPortVideoParam(), sizeof(*p));
433     // port supports OMX_COLOR_FormatYUV420SemiPlanar & OMX_COLOR_FormatAndroidOpaque
434     if (index == 1) {
435         p->nIndex = 1;
436         p->eColorFormat = OMX_COLOR_FormatAndroidOpaque;
437     }
438     return OMX_ErrorNone;
439 }
440 
SetParamVideoPortFormat(OMX_PTR pStructure)441 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) {
442     OMX_ERRORTYPE ret;
443     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
444 
445     CHECK_TYPE_HEADER(p);
446     CHECK_PORT_INDEX_RANGE(p);
447     CHECK_SET_PARAM_STATE();
448 
449     // TODO: do we need to check if port is enabled?
450     PortVideo *port = NULL;
451     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
452 #if 0
453     if (p->eColorFormat ==  OMX_COLOR_FormatAndroidOpaque) {
454         p->nIndex = 0;
455         p->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
456     }
457 #endif
458     port->SetPortVideoParam(p, false);
459     return OMX_ErrorNone;
460 }
461 
GetParamVideoBitrate(OMX_PTR pStructure)462 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoBitrate(OMX_PTR pStructure) {
463     OMX_ERRORTYPE ret;
464     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
465 
466     CHECK_TYPE_HEADER(p);
467     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
468     memcpy(p, &mParamBitrate, sizeof(*p));
469     return OMX_ErrorNone;
470 }
471 
SetParamVideoBitrate(OMX_PTR pStructure)472 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) {
473     OMX_ERRORTYPE ret;
474     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
475     CHECK_TYPE_HEADER(p);
476     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
477     CHECK_SET_PARAM_STATE();
478     OMX_U32 index = p->nPortIndex;
479     PortVideo *port = NULL;
480     // This disables other type of bitrate control mechanism
481     // TODO: check if it is desired
482 
483     // TODO: can we override  mParamBitrate.nPortIndex (See SetPortBitrateParam)
484     mParamBitrate.eControlRate = p->eControlRate;
485     mParamBitrate.nTargetBitrate = p->nTargetBitrate;
486 
487     port = static_cast<PortVideo *>(ports[index]);
488     ret = port->SetPortBitrateParam(p, false);
489     return OMX_ErrorNone;
490 }
491 
GetIntelPrivateInfo(OMX_PTR pStructure)492 OMX_ERRORTYPE OMXVideoEncoderBase::GetIntelPrivateInfo(OMX_PTR pStructure) {
493     OMX_ERRORTYPE ret;
494     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
495 
496     CHECK_TYPE_HEADER(p);
497     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
498     memcpy(p, &mConfigPriInfo, sizeof(*p));
499     return OMX_ErrorNone;
500 }
501 
SetIntelPrivateInfo(OMX_PTR pStructure)502 OMX_ERRORTYPE OMXVideoEncoderBase::SetIntelPrivateInfo(OMX_PTR pStructure) {
503     OMX_ERRORTYPE ret;
504     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
505     CHECK_TYPE_HEADER(p);
506     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
507 
508     // OMX_VIDEO_CONFIG_PRI_INFOTYPE is static parameter?
509     CHECK_SET_PARAM_STATE();
510 
511     // TODO: can we override  mConfigPriInfo.nPortIndex (See SetPortPrivateInfoParam)
512 
513     if(p->nHolder != NULL) {
514         // TODO: do we need to free nHolder?
515         if (mConfigPriInfo.nHolder) {
516             free(mConfigPriInfo.nHolder);
517         }
518         mConfigPriInfo.nCapacity = p->nCapacity;
519         // TODO: nCapacity is in 8-bit unit or 32-bit unit?
520         // TODO: check memory allocation
521         mConfigPriInfo.nHolder = (OMX_PTR)malloc(sizeof(OMX_U32) * p->nCapacity);
522         memcpy(mConfigPriInfo.nHolder, p->nHolder, sizeof(OMX_U32) * p->nCapacity);
523     } else {
524         mConfigPriInfo.nCapacity = 0;
525         mConfigPriInfo.nHolder = NULL;
526     }
527 
528     return OMX_ErrorNone;
529 }
530 
GetConfigIntelBitrate(OMX_PTR pStructure)531 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) {
532     OMX_ERRORTYPE ret;
533     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
534 
535     CHECK_TYPE_HEADER(p);
536     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
537     memcpy(p, &mConfigIntelBitrate, sizeof(*p));
538     return OMX_ErrorNone;
539 }
540 
SetConfigIntelBitrate(OMX_PTR pStructure)541 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) {
542     OMX_ERRORTYPE ret;
543     Encode_Status retStatus = ENCODE_SUCCESS;
544     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
545         LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
546         return OMX_ErrorUnsupportedIndex;
547     }
548     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
549     CHECK_TYPE_HEADER(p);
550     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
551 
552     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
553     mConfigIntelBitrate = *p;
554 
555     // return OMX_ErrorNone if not in Executing state
556     // TODO: return OMX_ErrorIncorrectStateOperation?
557     CHECK_SET_CONFIG_STATE();
558 
559     VideoConfigBitRate configBitRate;
560     configBitRate.rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
561     configBitRate.rcParams.initQP = mConfigIntelBitrate.nInitialQP;
562     configBitRate.rcParams.minQP = mConfigIntelBitrate.nMinQP;
563     configBitRate.rcParams.maxQP = mConfigIntelBitrate.nMaxQP;
564     configBitRate.rcParams.I_minQP = 0;
565     configBitRate.rcParams.I_maxQP = 0;
566     configBitRate.rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
567     configBitRate.rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
568     configBitRate.rcParams.enableIntraFrameQPControl = 0;
569     configBitRate.rcParams.temporalFrameRate = mConfigIntelBitrate.nFrameRate;
570     configBitRate.rcParams.temporalID = mConfigIntelBitrate.nTemporalID;
571     retStatus = mVideoEncoder->setConfig(&configBitRate);
572     if(retStatus != ENCODE_SUCCESS) {
573         LOGW("failed to set IntelBitrate");
574     }
575     return OMX_ErrorNone;
576 }
577 
GetConfigIntelAIR(OMX_PTR pStructure)578 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) {
579     OMX_ERRORTYPE ret;
580     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
581 
582     CHECK_TYPE_HEADER(p);
583     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
584     memcpy(p, &mConfigIntelAir, sizeof(*p));
585     return OMX_ErrorNone;
586 }
587 
SetConfigIntelAIR(OMX_PTR pStructure)588 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) {
589     OMX_ERRORTYPE ret;
590     Encode_Status retStatus = ENCODE_SUCCESS;
591 
592     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
593     CHECK_TYPE_HEADER(p);
594     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
595 
596     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
597     mConfigIntelAir = *p;
598 
599     // return OMX_ErrorNone if not in Executing state
600     // TODO: return OMX_ErrorIncorrectStateOperation?
601     CHECK_SET_CONFIG_STATE();
602 
603     VideoConfigAIR configAIR;
604     VideoConfigIntraRefreshType configIntraRefreshType;
605     if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
606         configAIR.airParams.airAuto = mConfigIntelAir.bAirAuto;
607         configAIR.airParams.airMBs = mConfigIntelAir.nAirMBs;
608         configAIR.airParams.airThreshold = mConfigIntelAir.nAirThreshold;
609         configIntraRefreshType.refreshType = VIDEO_ENC_AIR;
610     } else {
611         configIntraRefreshType.refreshType = VIDEO_ENC_NONIR;
612     }
613 
614     retStatus = mVideoEncoder->setConfig(&configAIR);
615     if(retStatus != ENCODE_SUCCESS) {
616         LOGW("Failed to set AIR config");
617     }
618 
619     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
620     if(retStatus != ENCODE_SUCCESS) {
621         LOGW("Failed to set refresh config");
622     }
623     return OMX_ErrorNone;
624 }
625 
GetParamVideoIntraRefresh(OMX_PTR pStructure)626 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoIntraRefresh(OMX_PTR pStructure) {
627     OMX_ERRORTYPE ret;
628     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
629 
630     CHECK_TYPE_HEADER(p);
631     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
632     memcpy(p, &mParamVideoRefresh, sizeof(*p));
633     return OMX_ErrorNone;
634 }
635 
SetParamVideoIntraRefresh(OMX_PTR pStructure)636 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoIntraRefresh(OMX_PTR pStructure) {
637     OMX_ERRORTYPE ret;
638     Encode_Status retStatus = ENCODE_SUCCESS;
639 
640     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
641     CHECK_TYPE_HEADER(p);
642     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
643 
644     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
645     mParamVideoRefresh = *p;
646 
647     // return OMX_ErrorNone if not in Executing state
648     // TODO: return OMX_ErrorIncorrectStateOperation?
649     CHECK_SET_PARAM_STATE();
650 
651     VideoConfigIntraRefreshType configIntraRefreshType;
652     configIntraRefreshType.refreshType = (VideoIntraRefreshType)(mParamVideoRefresh.eRefreshMode + 1);
653     if(configIntraRefreshType.refreshType == VIDEO_ENC_CIR){
654      VideoConfigCIR configCIR;
655         VideoConfigIntraRefreshType configIntraRefreshType;
656         configCIR.cirParams.cir_num_mbs = mParamVideoRefresh.nCirMBs;
657         configIntraRefreshType.refreshType = VIDEO_ENC_CIR;
658 
659         retStatus = mVideoEncoder->setConfig(&configCIR);
660         if(retStatus != ENCODE_SUCCESS) {
661             LOGW("Failed to set CIR config");
662         }
663     }else{
664         VideoConfigAIR configAIR;
665 
666         configAIR.airParams.airMBs = mParamVideoRefresh.nAirMBs;
667         configAIR.airParams.airThreshold = mParamVideoRefresh.nAirRef;
668 
669         retStatus = mVideoEncoder->setConfig(&configAIR);
670         if(retStatus != ENCODE_SUCCESS) {
671             LOGW("Failed to set AIR config");
672         }
673 
674     }
675 
676     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
677     if(retStatus != ENCODE_SUCCESS) {
678         LOGW("Failed to set refresh config");
679     }
680 
681     return OMX_ErrorNone;
682 }
683 
GetConfigVideoFramerate(OMX_PTR pStructure)684 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) {
685     OMX_ERRORTYPE ret;
686     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
687 
688     CHECK_TYPE_HEADER(p);
689     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
690     memcpy(p, &mConfigFramerate, sizeof(*p));
691     return OMX_ErrorNone;
692 }
693 
SetConfigVideoFramerate(OMX_PTR pStructure)694 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) {
695     OMX_ERRORTYPE ret;
696     Encode_Status retStatus = ENCODE_SUCCESS;
697     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
698         LOGE("SetConfigVideoFramerate failed. Feature is disabled.");
699         return OMX_ErrorUnsupportedIndex;
700     }
701     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
702     CHECK_TYPE_HEADER(p);
703     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
704 
705     // set in either Loaded state  (ComponentSetParam) or Executing state (ComponentSetConfig)
706     mConfigFramerate = *p;
707 
708     // return OMX_ErrorNone if not in Executing state
709     // TODO, return OMX_ErrorIncorrectStateOperation?
710     CHECK_SET_CONFIG_STATE();
711 
712     VideoConfigFrameRate framerate;
713     framerate.frameRate.frameRateDenom = 1;
714     framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate >> 16;
715     retStatus = mVideoEncoder->setConfig(&framerate);
716     if(retStatus != ENCODE_SUCCESS) {
717         LOGW("Failed to set frame rate config");
718     }
719     return OMX_ErrorNone;
720 }
721 
GetConfigVideoIntraVOPRefresh(OMX_PTR)722 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR) {
723     LOGW("GetConfigVideoIntraVOPRefresh is not supported.");
724     return OMX_ErrorUnsupportedSetting;
725 }
726 
SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure)727 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) {
728     OMX_ERRORTYPE ret;
729     Encode_Status retStatus = ENCODE_SUCCESS;
730     OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure;
731     CHECK_TYPE_HEADER(p);
732     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
733 
734     // return OMX_ErrorNone if not in Executing state
735     // TODO: return OMX_ErrorIncorrectStateOperation?
736     CHECK_SET_CONFIG_STATE();
737 
738     if(p->IntraRefreshVOP == OMX_TRUE) {
739         VideoParamConfigSet configIDRRequest;
740         configIDRRequest.type = VideoConfigTypeIDRRequest;
741         retStatus = mVideoEncoder->setConfig(&configIDRRequest);
742         if(retStatus != ENCODE_SUCCESS) {
743             LOGW("Failed to set refresh config");
744         }
745     }
746 
747     return OMX_ErrorNone;
748 }
749 
GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure)750 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
751 
752     OMX_ERRORTYPE ret;
753     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
754 
755     CHECK_TYPE_HEADER(p);
756     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
757     memcpy(p, &mParamIntelAdaptiveSliceControl, sizeof(*p));
758 
759     return OMX_ErrorNone;
760 }
761 
SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure)762 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
763 
764     OMX_ERRORTYPE ret;
765     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) {
766         LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled.");
767         return OMX_ErrorUnsupportedIndex;
768     }
769     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
770     CHECK_TYPE_HEADER(p);
771     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
772 
773     // set only in Loaded state (ComponentSetParam)
774     CHECK_SET_PARAM_STATE();
775 
776     mParamIntelAdaptiveSliceControl = *p;
777 
778     return OMX_ErrorNone;
779 }
780 
781 /*
782 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
783     OMX_ERRORTYPE ret;
784     OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
785 
786     CHECK_TYPE_HEADER(p);
787     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
788 
789     // assign values instead of memory coping to avoid nProfileIndex being overridden
790     p->eProfile = mParamProfileLevel.eProfile;
791     p->eLevel = mParamProfileLevel.eLevel;
792 
793     return OMX_ErrorNone;
794 }
795 
796 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
797     LOGW("SetParamVideoProfileLevelQuerySupported is not supported.");
798     return OMX_ErrorUnsupportedSetting;
799 }
800 */
801 
GetStoreMetaDataInBuffers(OMX_PTR pStructure)802 OMX_ERRORTYPE OMXVideoEncoderBase::GetStoreMetaDataInBuffers(OMX_PTR pStructure) {
803     OMX_ERRORTYPE ret;
804     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
805 
806     CHECK_TYPE_HEADER(p);
807     CHECK_PORT_INDEX(p, INPORT_INDEX);
808 
809     p->bStoreMetaData = mStoreMetaDataInBuffers;
810 
811     return OMX_ErrorNone;
812 };
SetStoreMetaDataInBuffers(OMX_PTR pStructure)813 OMX_ERRORTYPE OMXVideoEncoderBase::SetStoreMetaDataInBuffers(OMX_PTR pStructure) {
814     OMX_ERRORTYPE ret;
815     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
816     VideoParamsStoreMetaDataInBuffers StoreMetaDataInBuffers;
817     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
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 
GetConfigAndroidIntraRefresh(OMX_PTR pStructure)984 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigAndroidIntraRefresh(OMX_PTR pStructure) {
985     OMX_ERRORTYPE ret;
986     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure;
987 
988     CHECK_TYPE_HEADER(p);
989     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
990 
991     memcpy(p, &mConfigAndroidIntraRefresh, sizeof(*p));
992     return OMX_ErrorNone;
993 }
994 
SetConfigAndroidIntraRefresh(OMX_PTR pStructure)995 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigAndroidIntraRefresh(OMX_PTR pStructure) {
996     OMX_ERRORTYPE ret;
997 
998     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure;
999 
1000     CHECK_TYPE_HEADER(p);
1001     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
1002 
1003     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
1004     mConfigAndroidIntraRefresh = *p;
1005 
1006     // return OMX_ErrorNone if not in Executing state
1007     // TODO: return OMX_ErrorIncorrectStateOperation?
1008     CHECK_SET_PARAM_STATE();
1009 
1010     OMX_VIDEO_PARAM_INTRAREFRESHTYPE intraRefresh;
1011     memset(&intraRefresh, 0, sizeof(intraRefresh));
1012     intraRefresh.nSize = sizeof(intraRefresh);
1013     intraRefresh.nVersion = p->nVersion;
1014     intraRefresh.nPortIndex = mConfigAndroidIntraRefresh.nPortIndex;
1015     intraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
1016     intraRefresh.nAirMBs = 0;
1017     intraRefresh.nAirRef = 0;
1018 
1019     if (0 == mConfigAndroidIntraRefresh.nRefreshPeriod) {
1020         intraRefresh.nCirMBs = 0;
1021     } else {
1022         OMX_PARAM_PORTDEFINITIONTYPE def;
1023 
1024         if (intraRefresh.nPortIndex < nr_ports) {
1025             memcpy(&def, ports[intraRefresh.nPortIndex]->GetPortDefinition(),sizeof(def));
1026         } else {
1027             LOGW("Failed tp set AIR config, bad port index");
1028             return OMX_ErrorBadPortIndex;
1029         }
1030 
1031         intraRefresh.nCirMBs = divUp((divUp(def.format.video.nFrameWidth, 16u) * divUp(def.format.video.nFrameHeight,16u)), mConfigAndroidIntraRefresh.nRefreshPeriod);
1032     }
1033     return SetParamVideoIntraRefresh(&intraRefresh);
1034 }
1035