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
25static const char *RAW_MIME_TYPE = "video/raw";
26
27OMXVideoEncoderBase::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
50OMXVideoEncoderBase::~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
82OMX_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
141OMX_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
274OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
275    // no format specific to initialize input
276    return OMX_ErrorNone;
277}
278
279OMX_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
353OMX_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
367OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) {
368    if(mVideoEncoder) {
369        mVideoEncoder->stop();
370    }
371
372    return OMX_ErrorNone;
373}
374
375OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) {
376
377    this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
378    return OMX_ErrorNone;
379}
380OMX_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
389OMX_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
398OMX_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
420OMX_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
441OMX_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
462OMX_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
472OMX_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
492OMX_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
502OMX_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
531OMX_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
541OMX_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
578OMX_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
588OMX_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
626OMX_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
636OMX_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
684OMX_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
694OMX_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
722OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR) {
723    LOGW("GetConfigVideoIntraVOPRefresh is not supported.");
724    return OMX_ErrorUnsupportedSetting;
725}
726
727OMX_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
750OMX_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
762OMX_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/*
782OMX_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
796OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
797    LOGW("SetParamVideoProfileLevelQuerySupported is not supported.");
798    return OMX_ErrorUnsupportedSetting;
799}
800*/
801
802OMX_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};
813OMX_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
853OMX_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
861OMX_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
871OMX_ERRORTYPE OMXVideoEncoderBase::GetPrependSPSPPS(OMX_PTR) {
872    return OMX_ErrorNone;
873};
874
875OMX_ERRORTYPE OMXVideoEncoderBase::SetPrependSPSPPS(OMX_PTR) {
876    LOGD("SetPrependSPSPPS success");
877    return OMX_ErrorNone;
878};
879
880OMX_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
890OMX_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
913OMX_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
942OMX_ERRORTYPE OMXVideoEncoderBase::SetBlackFramePointer(OMX_PTR) {
943    return OMX_ErrorUnsupportedSetting;
944}
945
946OMX_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}
956OMX_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
984OMX_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
995OMX_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