1/*--------------------------------------------------------------------------
2Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6    * Redistributions of source code must retain the above copyright
7      notice, this list of conditions and the following disclaimer.
8    * Redistributions in binary form must reproduce the above copyright
9      notice, this list of conditions and the following disclaimer in the
10      documentation and/or other materials provided with the distribution.
11    * Neither the name of The Linux Foundation nor
12      the names of its contributors may be used to endorse or promote
13      products derived from this software without specific prior written
14      permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28#include "omx_swvenc_mpeg4.h"
29
30/* def: StoreMetaDataInBuffersParams */
31#include <media/hardware/HardwareAPI.h>
32
33/* def: VENUS_BUFFER_SIZE, VENUS_Y_STRIDE etc */
34#include <media/msm_media_info.h>
35
36/* def: private_handle_t*/
37#include <gralloc_priv.h>
38
39
40/*----------------------------------------------------------------------------
41 * Preprocessor Definitions and Constants
42 * -------------------------------------------------------------------------*/
43#define OMX_SPEC_VERSION 0x00000101
44#define OMX_INIT_STRUCT(_s_, _name_)             \
45    memset((_s_), 0x0, sizeof(_name_));          \
46    (_s_)->nSize = sizeof(_name_);               \
47    (_s_)->nVersion.nVersion = OMX_SPEC_VERSION
48
49#define ENTER_FUNC() DEBUG_PRINT_HIGH("ENTERING: %s",__FUNCTION__)
50#define EXIT_FUNC()  DEBUG_PRINT_HIGH("EXITING: %s",__FUNCTION__)
51#define RETURN(x)    EXIT_FUNC(); return x;
52#define ALIGN(value,alignment) (((value) + (alignment-1)) & (~(alignment-1)))
53
54#define BUFFER_LOG_LOC "/data/misc/media"
55
56/* factory function executed by the core to create instances */
57void *get_omx_component_factory_fn(void)
58{
59    RETURN((new omx_venc));
60}
61
62omx_venc::omx_venc()
63{
64    ENTER_FUNC();
65
66    char property_value[PROPERTY_VALUE_MAX] = {0};
67
68    memset(&m_debug,0,sizeof(m_debug));
69
70    property_value[0] = '\0';
71    property_get("vidc.debug.level", property_value, "1");
72    debug_level = atoi(property_value);
73
74    property_value[0] = '\0';
75    property_get("vidc.enc.log.in", property_value, "0");
76    m_debug.in_buffer_log = atoi(property_value);
77
78    property_value[0] = '\0';
79    property_get("vidc.enc.log.out", property_value, "0");
80    m_debug.out_buffer_log = atoi(property_value);
81
82    snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
83    property_value[0] = '\0';
84    property_get("vidc.log.loc", property_value, "");
85    if (*property_value)
86    {
87       strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
88    }
89
90    memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
91    meta_mode_enable = false;
92    memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
93    memset(meta_buffers,0,sizeof(meta_buffers));
94    memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr));
95    mUseProxyColorFormat = false;
96    get_syntaxhdr_enable = false;
97    m_bSeqHdrRequested = false;
98    set_format = false;
99
100    EXIT_FUNC();
101}
102
103omx_venc::~omx_venc()
104{
105    ENTER_FUNC();
106    get_syntaxhdr_enable = false;
107    EXIT_FUNC();
108}
109
110OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
111{
112    ENTER_FUNC();
113
114    OMX_ERRORTYPE eRet = OMX_ErrorNone;
115    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
116    SWVENC_CALLBACK callBackInfo;
117    OMX_VIDEO_CODINGTYPE codec_type;
118    SWVENC_PROPERTY Prop;
119    int fds[2];
120
121    strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
122    secure_session = false;
123
124    if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.mpeg4sw",
125                  OMX_MAX_STRINGNAME_SIZE))
126    {
127        strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
128                OMX_MAX_STRINGNAME_SIZE);
129        codec_type = OMX_VIDEO_CodingMPEG4;
130        m_codec = SWVENC_CODEC_MPEG4;
131    }
132    else if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.h263sw",
133                  OMX_MAX_STRINGNAME_SIZE))
134    {
135        strlcpy((char *)m_cRole, "video_encoder.h263",\
136                OMX_MAX_STRINGNAME_SIZE);
137        codec_type = OMX_VIDEO_CodingH263;
138        m_codec = SWVENC_CODEC_H263;
139    }
140    else
141    {
142        DEBUG_PRINT_ERROR("ERROR: Unknown Component");
143        eRet = OMX_ErrorInvalidComponentName;
144        RETURN(eRet);
145    }
146
147#ifdef ENABLE_GET_SYNTAX_HDR
148    get_syntaxhdr_enable = true;
149    DEBUG_PRINT_HIGH("Get syntax header enabled");
150#endif
151
152    callBackInfo.pfn_empty_buffer_done    = swvenc_empty_buffer_done_cb;
153    callBackInfo.pfn_fill_buffer_done     = swvenc_fill_buffer_done_cb;
154    callBackInfo.pfn_event_notification   = swvenc_handle_event_cb;
155    callBackInfo.p_client                 = (void*)this;
156
157    SWVENC_STATUS sRet = swvenc_init(&m_hSwVenc, m_codec, &callBackInfo);
158    if (sRet != SWVENC_S_SUCCESS)
159    {
160        DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources",
161         sRet);
162        RETURN(OMX_ErrorInsufficientResources);
163    }
164
165    m_stopped = true;
166
167    //Intialise the OMX layer variables
168    memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE));
169
170    OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE);
171    m_sPortParam.nPorts = 0x2;
172    m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN;
173
174    OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE);
175    m_sPortParam_audio.nPorts = 0;
176    m_sPortParam_audio.nStartPortNumber = 0;
177
178    OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE);
179    m_sPortParam_img.nPorts = 0;
180    m_sPortParam_img.nStartPortNumber = 0;
181
182    OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE);
183    m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
184    m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames;
185    m_sParamBitrate.nTargetBitrate = 64000;
186
187    OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE);
188    m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
189    m_sConfigBitrate.nEncodeBitrate = 64000;
190
191    OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE);
192    m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
193    m_sConfigFramerate.xEncodeFramerate = 30 << 16;
194
195    OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE);
196    m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
197    m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE;
198
199    OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE);
200    m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN;
201    m_sConfigFrameRotation.nRotation = 0;
202
203    OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
204    m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
205    m_sSessionQuantization.nQpI = 9;
206    m_sSessionQuantization.nQpP = 6;
207    m_sSessionQuantization.nQpB = 2;
208
209    OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE);
210    m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
211    m_sSessionQPRange.minQP = 2;
212
213    OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
214    m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
215
216    OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE);
217    m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
218    m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1;
219
220    OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
221    m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
222    m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE;
223    m_sErrorCorrection.bEnableHEC = OMX_FALSE;
224    m_sErrorCorrection.bEnableResync = OMX_FALSE;
225    m_sErrorCorrection.bEnableRVLC = OMX_FALSE;
226    m_sErrorCorrection.nResynchMarkerSpacing = 0;
227
228    OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
229    m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
230    m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax;
231
232    if (codec_type == OMX_VIDEO_CodingMPEG4)
233    {
234        m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple;
235        m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0;
236    } else if (codec_type == OMX_VIDEO_CodingH263)
237    {
238        m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline;
239        m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10;
240    }
241
242    /* set the profile and level */
243    Ret = swvenc_set_profile_level(m_sParamProfileLevel.eProfile,
244                m_sParamProfileLevel.eLevel);
245    if (Ret != SWVENC_S_SUCCESS)
246    {
247       DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
248         __FUNCTION__, Ret);
249       RETURN(OMX_ErrorUndefined);
250    }
251
252    // Initialize the video parameters for input port
253    OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
254    m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN;
255    m_sInPortDef.bEnabled = OMX_TRUE;
256    m_sInPortDef.bPopulated = OMX_FALSE;
257    m_sInPortDef.eDomain = OMX_PortDomainVideo;
258    m_sInPortDef.eDir = OMX_DirInput;
259    m_sInPortDef.format.video.cMIMEType = (char *)"YUV420";
260    m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
261    m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
262    m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH;
263    m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT;
264    m_sInPortDef.format.video.nBitrate = 64000;
265    m_sInPortDef.format.video.xFramerate = 15 << 16;
266    m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
267        QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
268    m_sInPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingUnused;
269
270    /* set the frame size */
271    Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
272    Prop.info.frame_size.height = m_sInPortDef.format.video.nFrameHeight;
273    Prop.info.frame_size.width  = m_sInPortDef.format.video.nFrameWidth;
274
275    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
276    if (Ret != SWVENC_S_SUCCESS)
277    {
278       DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
279         __FUNCTION__, Ret);
280       RETURN(OMX_ErrorUnsupportedSetting);
281    }
282
283    /* set the frame attributes */
284    Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
285    Prop.info.frame_attributes.stride_luma = m_sInPortDef.format.video.nStride;
286    Prop.info.frame_attributes.stride_chroma = m_sInPortDef.format.video.nStride;
287    Prop.info.frame_attributes.offset_luma = 0;
288    Prop.info.frame_attributes.offset_chroma =
289      (m_sInPortDef.format.video.nSliceHeight * m_sInPortDef.format.video.nStride);
290    Prop.info.frame_attributes.size = (Prop.info.frame_attributes.offset_chroma * 3) >> 1;
291
292    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
293    if (Ret != SWVENC_S_SUCCESS)
294    {
295       DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
296         __FUNCTION__, Ret);
297       RETURN(OMX_ErrorUndefined);
298    }
299
300    Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
301              &m_sInPortDef.nBufferCountActual,
302              &m_sInPortDef.nBufferSize,
303              &m_sInPortDef.nBufferAlignment,
304              PORT_INDEX_IN);
305    if (Ret != SWVENC_S_SUCCESS)
306    {
307       DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
308          Ret);
309       RETURN(OMX_ErrorUndefined);
310    }
311
312    // Initialize the video parameters for output port
313    OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
314    m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
315    m_sOutPortDef.bEnabled = OMX_TRUE;
316    m_sOutPortDef.bPopulated = OMX_FALSE;
317    m_sOutPortDef.eDomain = OMX_PortDomainVideo;
318    m_sOutPortDef.eDir = OMX_DirOutput;
319    m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
320    m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
321    m_sOutPortDef.format.video.nBitrate = 64000;
322    m_sOutPortDef.format.video.xFramerate = 15 << 16;
323    m_sOutPortDef.format.video.eColorFormat =  OMX_COLOR_FormatUnused;
324    if (codec_type == OMX_VIDEO_CodingMPEG4)
325    {
326        m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingMPEG4;
327    }
328    else if (codec_type == OMX_VIDEO_CodingH263)
329    {
330        m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingH263;
331    }
332
333    Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
334              &m_sOutPortDef.nBufferCountActual,
335              &m_sOutPortDef.nBufferSize,
336              &m_sOutPortDef.nBufferAlignment,
337              PORT_INDEX_OUT);
338    if (Ret != SWVENC_S_SUCCESS)
339    {
340       DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
341          Ret);
342       RETURN(OMX_ErrorUndefined);
343    }
344
345    // Initialize the video color format for input port
346    OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
347    m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN;
348    m_sInPortFormat.nIndex = 0;
349    m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
350        QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
351    m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
352
353    // Initialize the compression format for output port
354    OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
355    m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
356    m_sOutPortFormat.nIndex = 0;
357    m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused;
358    if (codec_type == OMX_VIDEO_CodingMPEG4)
359    {
360        m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingMPEG4;
361    } else if (codec_type == OMX_VIDEO_CodingH263)
362    {
363        m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingH263;
364    }
365
366    // mandatory Indices for kronos test suite
367    OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE);
368
369    OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
370    m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN;
371
372    OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
373    m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
374
375    OMX_INIT_STRUCT(&m_sParamInitqp, QOMX_EXTNINDEX_VIDEO_INITIALQP);
376    m_sParamInitqp.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
377
378    // mp4 specific init
379    OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE);
380    m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
381    m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
382    m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0;
383    m_sParamMPEG4.nSliceHeaderSpacing = 0;
384    m_sParamMPEG4.bSVH = OMX_FALSE;
385    m_sParamMPEG4.bGov = OMX_FALSE;
386    // 2 second intra period for default outport fps
387    m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
388    m_sParamMPEG4.bACPred = OMX_TRUE;
389    // delta = 2 @ 15 fps
390    m_sParamMPEG4.nTimeIncRes = 30;
391    // pframe and iframe
392    m_sParamMPEG4.nAllowedPictureTypes = 2;
393    // number of video packet headers per vop
394    m_sParamMPEG4.nHeaderExtension = 1;
395    m_sParamMPEG4.bReversibleVLC = OMX_FALSE;
396
397    // h263 specific init
398    OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE);
399    m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
400    // 2 second intra period for default outport fps
401    m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
402    m_sParamH263.nBFrames = 0;
403    m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline;
404    m_sParamH263.eLevel = OMX_VIDEO_H263Level10;
405    m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE;
406    m_sParamH263.nAllowedPictureTypes = 2;
407    m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE;
408    m_sParamH263.nPictureHeaderRepetition = 0;
409    m_sParamH263.nGOBHeaderInterval = 1;
410
411    m_state                   = OMX_StateLoaded;
412    m_sExtraData = 0;
413
414    m_capability.max_height = OMX_CORE_FWVGA_HEIGHT;
415    m_capability.max_width = OMX_CORE_FWVGA_WIDTH;
416    m_capability.min_height = 32;
417    m_capability.min_width = 32;
418
419    if (eRet == OMX_ErrorNone)
420    {
421        if (pipe(fds))
422        {
423            DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
424            eRet = OMX_ErrorInsufficientResources;
425        }
426        else
427        {
428            if ((fds[0] == 0) || (fds[1] == 0))
429            {
430                if (pipe(fds))
431                {
432                    DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
433                    eRet = OMX_ErrorInsufficientResources;
434                }
435            }
436            if (eRet == OMX_ErrorNone)
437            {
438                m_pipe_in = fds[0];
439                m_pipe_out = fds[1];
440            }
441        }
442
443        if (pthread_create(&msg_thread_id,0, message_thread_enc, this) < 0)
444        {
445            eRet = OMX_ErrorInsufficientResources;
446            msg_thread_created = false;
447        }
448        else
449        {
450            msg_thread_created = true;
451        }
452    }
453
454    DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet);
455
456    EXIT_FUNC();
457
458    RETURN(eRet);
459}
460
461OMX_ERRORTYPE  omx_venc::set_parameter
462(
463    OMX_IN OMX_HANDLETYPE hComp,
464    OMX_IN OMX_INDEXTYPE  paramIndex,
465    OMX_IN OMX_PTR        paramData
466)
467{
468    ENTER_FUNC();
469
470    OMX_ERRORTYPE eRet = OMX_ErrorNone;
471    SWVENC_STATUS Ret  = SWVENC_S_SUCCESS;
472    SWVENC_PROPERTY Prop;
473    bool bResult;
474    unsigned int stride, scanlines;
475
476    (void)hComp;
477
478    if (m_state == OMX_StateInvalid)
479    {
480        DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State");
481        RETURN(OMX_ErrorInvalidState);
482    }
483    if (paramData == NULL)
484    {
485        DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
486        RETURN(OMX_ErrorBadParameter);
487    }
488
489    /* set_parameter can be called in loaded state or disabled port */
490    if ( (m_state == OMX_StateLoaded) ||
491         (m_sInPortDef.bEnabled == OMX_FALSE) ||
492         (m_sOutPortDef.bEnabled == OMX_FALSE)
493       )
494    {
495        DEBUG_PRINT_LOW("Set Parameter called in valid state");
496    }
497    else
498    {
499        DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
500        RETURN(OMX_ErrorIncorrectStateOperation);
501    }
502
503    switch ((int)paramIndex)
504    {
505        case OMX_IndexParamPortDefinition:
506        {
507            OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
508            portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
509            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
510                    (int)portDefn->format.video.nFrameHeight,
511                    (int)portDefn->format.video.nFrameWidth);
512
513            if (PORT_INDEX_IN == portDefn->nPortIndex)
514            {
515                if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth,
516                            portDefn->format.video.nFrameHeight))
517                {
518                    DEBUG_PRINT_ERROR("video session not supported");
519                    omx_report_unsupported_setting();
520                    RETURN(OMX_ErrorUnsupportedSetting);
521                }
522                DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual);
523                DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin);
524                DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize);
525                if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
526                {
527                    DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
528                            portDefn->nBufferCountMin, portDefn->nBufferCountActual);
529                    RETURN(OMX_ErrorUnsupportedSetting);
530                }
531
532                /* set the frame size */
533                Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
534                Prop.info.frame_size.height = portDefn->format.video.nFrameHeight;
535                Prop.info.frame_size.width  = portDefn->format.video.nFrameWidth;
536
537                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
538                if (Ret != SWVENC_S_SUCCESS)
539                {
540                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
541                     __FUNCTION__, Ret);
542                   RETURN(OMX_ErrorUnsupportedSetting);
543                }
544
545                /* set the input frame-rate */
546                if (portDefn->format.video.xFramerate != 0)
547                {
548                   Ret = swvenc_set_frame_rate(portDefn->format.video.xFramerate >> 16);
549                   if (Ret != SWVENC_S_SUCCESS)
550                   {
551                      DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
552                        __FUNCTION__, Ret);
553                      RETURN(OMX_ErrorUnsupportedSetting);
554                   }
555                }
556
557                /* set the frame attributes */
558                stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
559                scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nSliceHeight);
560                Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
561                Prop.info.frame_attributes.stride_luma = stride;
562                Prop.info.frame_attributes.stride_chroma = stride;
563                Prop.info.frame_attributes.offset_luma = 0;
564                Prop.info.frame_attributes.offset_chroma = scanlines * stride;
565                Prop.info.frame_attributes.size =
566                  VENUS_BUFFER_SIZE(COLOR_FMT_NV12,
567                     portDefn->format.video.nFrameWidth,
568                     portDefn->format.video.nFrameHeight);
569
570                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
571                if (Ret != SWVENC_S_SUCCESS)
572                {
573                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
574                     __FUNCTION__, Ret);
575                   RETURN(OMX_ErrorUnsupportedSetting);
576                }
577
578                DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual);
579                DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin);
580                DEBUG_PRINT_LOW("i/p previous buffersize = %u", m_sInPortDef.nBufferSize);
581
582                memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
583
584                /* update the input buffer requirement */
585                Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
586                        &m_sInPortDef.nBufferCountActual,
587                        &m_sInPortDef.nBufferSize,
588                        &m_sInPortDef.nBufferAlignment,
589                        portDefn->nPortIndex);
590                if (Ret != SWVENC_S_SUCCESS)
591                {
592                   DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
593                      Ret);
594                   RETURN(OMX_ErrorUndefined);
595                }
596
597                if (portDefn->nBufferCountActual > m_sInPortDef.nBufferCountActual)
598                {
599                   m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual;
600                }
601                if (portDefn->nBufferSize > m_sInPortDef.nBufferSize)
602                {
603                   m_sInPortDef.nBufferSize = portDefn->nBufferSize;
604                }
605
606                DEBUG_PRINT_LOW("i/p new actual cnt = %u", m_sInPortDef.nBufferCountActual);
607                DEBUG_PRINT_LOW("i/p new min cnt = %u", m_sInPortDef.nBufferCountMin);
608                DEBUG_PRINT_LOW("i/p new buffersize = %u", m_sInPortDef.nBufferSize);
609            }
610            else if (PORT_INDEX_OUT == portDefn->nPortIndex)
611            {
612                DEBUG_PRINT_LOW("o/p actual cnt requested = %u", portDefn->nBufferCountActual);
613                DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin);
614                DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize);
615                if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
616                {
617                    DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
618                            portDefn->nBufferCountMin, portDefn->nBufferCountActual);
619                    RETURN(OMX_ErrorUnsupportedSetting);
620                }
621
622                /* set the output bit-rate */
623                Ret = swvenc_set_bit_rate(portDefn->format.video.nBitrate);
624                if (Ret != SWVENC_S_SUCCESS)
625                {
626                   DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
627                     __FUNCTION__, Ret);
628                   RETURN(OMX_ErrorUnsupportedSetting);
629                }
630
631                DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
632                DEBUG_PRINT_LOW("o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
633                DEBUG_PRINT_LOW("o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
634
635                /* set the buffer requirement */
636                bResult = dev_set_buf_req(&portDefn->nBufferCountMin,
637                  &portDefn->nBufferCountActual,
638                  &portDefn->nBufferSize,
639                  portDefn->nPortIndex);
640                if (bResult != true)
641                {
642                   DEBUG_PRINT_ERROR("%s, dev_set_buf_req failed",
643                     __FUNCTION__);
644                   RETURN(OMX_ErrorUnsupportedSetting);
645                }
646                memcpy(&m_sOutPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
647
648                /* update the output buffer requirement */
649                Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
650                        &m_sOutPortDef.nBufferCountActual,
651                        &m_sOutPortDef.nBufferSize,
652                        &m_sOutPortDef.nBufferAlignment,
653                        portDefn->nPortIndex);
654                if (Ret != SWVENC_S_SUCCESS)
655                {
656                   DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
657                      Ret);
658                   RETURN(OMX_ErrorUndefined);
659                }
660
661                if (portDefn->nBufferCountActual > m_sOutPortDef.nBufferCountActual)
662                {
663                   m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual;
664                }
665                if (portDefn->nBufferSize > m_sOutPortDef.nBufferSize)
666                {
667                   m_sOutPortDef.nBufferSize = portDefn->nBufferSize;
668                }
669
670                DEBUG_PRINT_LOW("o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
671                DEBUG_PRINT_LOW("o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
672                DEBUG_PRINT_LOW("o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
673            }
674            else
675            {
676                DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d",
677                        (int)portDefn->nPortIndex);
678                eRet = OMX_ErrorBadPortIndex;
679            }
680            m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate;
681            m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate;
682            m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate;
683            break;
684        }
685
686        case OMX_IndexParamVideoPortFormat:
687        {
688            OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
689                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
690            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
691                    portFmt->eColorFormat);
692            SWVENC_COLOR_FORMAT color_format;
693
694            /* set the driver with the corresponding values */
695            if (PORT_INDEX_IN == portFmt->nPortIndex)
696            {
697                if (portFmt->eColorFormat ==
698                    ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
699                {
700                    /* meta_mode = 2 (kMetadataBufferTypeGrallocSource) */
701                    m_sInPortFormat.eColorFormat =
702                        (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
703                    color_format = SWVENC_COLOR_FORMAT_NV12;
704                    if (!mUseProxyColorFormat)
705                    {
706                       if (!c2d_conv.init())
707                       {
708                          DEBUG_PRINT_ERROR("C2D init failed");
709                          return OMX_ErrorUnsupportedSetting;
710                       }
711                       DEBUG_PRINT_ERROR("C2D init is successful");
712                    }
713                    mUseProxyColorFormat = true;
714                    m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ;
715                }
716                else
717                {
718                    m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
719                    if ((portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) ||
720                        (portFmt->eColorFormat ==
721                         ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
722                    {
723                        color_format = SWVENC_COLOR_FORMAT_NV12;
724                    }
725                    else if (portFmt->eColorFormat ==
726                             ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
727                    {
728                        color_format = SWVENC_COLOR_FORMAT_NV21;
729                    }
730                    else
731                    {
732                        DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat %d invalid",
733                                          __FUNCTION__,
734                                          portFmt->eColorFormat);
735                        RETURN(OMX_ErrorBadParameter);
736                    }
737                    m_input_msg_id = OMX_COMPONENT_GENERATE_ETB;
738                    mUseProxyColorFormat = false;
739                }
740                m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
741                /* set the input color format */
742                Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
743                Prop.info.color_format = color_format;
744                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
745                if (Ret != SWVENC_S_SUCCESS)
746                {
747                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
748                     __FUNCTION__, Ret);
749                   RETURN(OMX_ErrorUnsupportedSetting);
750                }
751
752                /* set the input frame-rate */
753                if (portFmt->xFramerate != 0)
754                {
755                   Ret = swvenc_set_frame_rate(portFmt->xFramerate >> 16);
756                   if (Ret != SWVENC_S_SUCCESS)
757                   {
758                      DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
759                        __FUNCTION__, Ret);
760                      //RETURN(OMX_ErrorUnsupportedSetting);
761                   }
762                   m_sInPortFormat.xFramerate = portFmt->xFramerate;
763                }
764            }
765            break;
766        }
767
768        case OMX_IndexParamVideoInit:
769        {
770            OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
771            DEBUG_PRINT_LOW("Set OMX_IndexParamVideoInit called");
772            break;
773        }
774
775        case OMX_IndexParamVideoBitrate:
776        {
777            OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
778            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate");
779
780            if (m_max_allowed_bitrate_check)
781            {
782               //TBD: to add bitrate check
783            }
784
785            /* set the output bit-rate */
786            Ret = swvenc_set_bit_rate(pParam->nTargetBitrate);
787            if (Ret != SWVENC_S_SUCCESS)
788            {
789               DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
790                 __FUNCTION__, Ret);
791               RETURN(OMX_ErrorUnsupportedSetting);
792            }
793
794            /* set the RC-mode */
795            Ret = swvenc_set_rc_mode(pParam->eControlRate);
796            if (Ret != SWVENC_S_SUCCESS)
797            {
798               DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
799                 __FUNCTION__, Ret);
800               RETURN(OMX_ErrorUnsupportedSetting);
801            }
802
803            m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate;
804            m_sParamBitrate.eControlRate = pParam->eControlRate;
805            m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate;
806            m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate;
807            m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate;
808            DEBUG_PRINT_LOW("bitrate = %u", m_sOutPortDef.format.video.nBitrate);
809            break;
810        }
811
812        case OMX_IndexParamVideoMpeg4:
813        {
814            OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
815
816            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4");
817
818            if (pParam->nBFrames)
819            {
820                DEBUG_PRINT_ERROR("Warning: B frames not supported");
821            }
822
823            /* set the intra period */
824            Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
825            if (Ret != SWVENC_S_SUCCESS)
826            {
827               DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
828                 __FUNCTION__, Ret);
829               RETURN(OMX_ErrorUnsupportedSetting);
830            }
831
832            memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
833            m_sIntraperiod.nPFrames = m_sParamMPEG4.nPFrames;
834            m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames;
835            break;
836        }
837
838        case OMX_IndexParamVideoH263:
839        {
840            OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
841
842            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263");
843
844            /* set the intra period */
845            Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
846            if (Ret != SWVENC_S_SUCCESS)
847            {
848               DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
849                 __FUNCTION__, Ret);
850               RETURN(OMX_ErrorUnsupportedSetting);
851            }
852
853            memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE));
854            m_sIntraperiod.nPFrames = m_sParamH263.nPFrames;
855            m_sIntraperiod.nBFrames = m_sParamH263.nBFrames;
856            break;
857        }
858
859        case OMX_IndexParamVideoProfileLevelCurrent:
860        {
861            OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
862
863            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
864
865            /* set the profile and level */
866            Ret = swvenc_set_profile_level(pParam->eProfile,pParam->eLevel);
867            if (Ret != SWVENC_S_SUCCESS)
868            {
869               DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
870                 __FUNCTION__, Ret);
871               RETURN(OMX_ErrorUnsupportedSetting);
872            }
873
874
875            m_sParamProfileLevel.eProfile = pParam->eProfile;
876            m_sParamProfileLevel.eLevel = pParam->eLevel;
877
878            if (SWVENC_CODEC_MPEG4 == m_codec)
879            {
880                m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile;
881                m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel;
882                DEBUG_PRINT_LOW("MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
883                        m_sParamMPEG4.eLevel);
884            }
885            else if (SWVENC_CODEC_H263 == m_codec)
886            {
887                m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile;
888                m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel;
889                DEBUG_PRINT_LOW("H263 profile = %d, level = %d", m_sParamH263.eProfile,
890                        m_sParamH263.eLevel);
891            }
892            break;
893        }
894
895        case OMX_IndexParamStandardComponentRole:
896        {
897            OMX_PARAM_COMPONENTROLETYPE *comp_role;
898            comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
899            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
900                    comp_role->cRole);
901
902            if ((m_state == OMX_StateLoaded)&&
903                    !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
904            {
905                DEBUG_PRINT_LOW("Set Parameter called in valid state");
906            }
907            else
908            {
909                DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
910                RETURN(OMX_ErrorIncorrectStateOperation);
911            }
912
913            if (SWVENC_CODEC_MPEG4 == m_codec)
914            {
915                if (!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
916                {
917                    strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
918                }
919                else
920                {
921                    DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
922                    eRet = OMX_ErrorUnsupportedSetting;
923                }
924            }
925            else if (SWVENC_CODEC_H263 == m_codec)
926            {
927                if (!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE))
928                {
929                    strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
930                }
931                else
932                {
933                    DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
934                    eRet =OMX_ErrorUnsupportedSetting;
935                }
936            }
937            else
938            {
939                DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", m_nkind);
940                eRet = OMX_ErrorInvalidComponentName;
941            }
942            break;
943        }
944
945        case OMX_IndexParamPriorityMgmt:
946        {
947            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt");
948            if (m_state != OMX_StateLoaded) {
949                DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
950                RETURN(OMX_ErrorIncorrectStateOperation);
951            }
952            OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
953            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
954                    priorityMgmtype->nGroupID);
955
956            DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
957                    priorityMgmtype->nGroupPriority);
958
959            m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID;
960            m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority;
961
962            break;
963        }
964
965        case OMX_IndexParamCompBufferSupplier:
966        {
967            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier");
968            OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
969            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
970                    bufferSupplierType->eBufferSupplier);
971            if ( (bufferSupplierType->nPortIndex == 0) ||
972                 (bufferSupplierType->nPortIndex ==1)
973               )
974            {
975                m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
976            }
977            else
978            {
979                eRet = OMX_ErrorBadPortIndex;
980            }
981
982            break;
983
984        }
985
986        case OMX_IndexParamVideoQuantization:
987        {
988            // this is applicable only for RC-off case
989            DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization");
990            OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
991            if (session_qp->nPortIndex == PORT_INDEX_OUT)
992            {
993                Prop.id = SWVENC_PROPERTY_ID_QP;
994                Prop.info.qp.qp_i = session_qp->nQpI;
995                Prop.info.qp.qp_p = session_qp->nQpP;
996                Prop.info.qp.qp_b = session_qp->nQpB;
997
998                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
999                if (Ret != SWVENC_S_SUCCESS)
1000                {
1001                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1002                     __FUNCTION__, Ret);
1003                   RETURN(OMX_ErrorUnsupportedSetting);
1004                }
1005
1006                m_sSessionQuantization.nQpI = session_qp->nQpI;
1007                m_sSessionQuantization.nQpP = session_qp->nQpP;
1008                m_sSessionQuantization.nQpB = session_qp->nQpB;
1009            }
1010            else
1011            {
1012                DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
1013                eRet = OMX_ErrorBadPortIndex;
1014            }
1015            break;
1016        }
1017
1018        case OMX_QcomIndexParamVideoQPRange:
1019        {
1020            DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange");
1021            OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
1022            if (qp_range->nPortIndex == PORT_INDEX_OUT)
1023            {
1024                if ( (qp_range->minQP > 255) ||
1025                     (qp_range->maxQP > 255)
1026                   )
1027                {
1028                   DEBUG_PRINT_ERROR("ERROR: Out of range QP");
1029                   eRet = OMX_ErrorBadParameter;
1030                }
1031
1032                Prop.id = SWVENC_PROPERTY_ID_QP_RANGE;
1033                Prop.info.qp_range.min_qp_packed =
1034                 (qp_range->minQP << 16) | (qp_range->minQP) | (qp_range->minQP << 8);
1035                Prop.info.qp_range.max_qp_packed =
1036                 (qp_range->maxQP << 16) | (qp_range->maxQP) | (qp_range->maxQP << 8);
1037
1038                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1039                if (Ret != SWVENC_S_SUCCESS)
1040                {
1041                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1042                     __FUNCTION__, Ret);
1043                   RETURN(OMX_ErrorUnsupportedSetting);
1044                }
1045
1046                m_sSessionQPRange.minQP= qp_range->minQP;
1047                m_sSessionQPRange.maxQP= qp_range->maxQP;
1048            }
1049            else
1050            {
1051                DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for QP range setting");
1052                eRet = OMX_ErrorBadPortIndex;
1053            }
1054            break;
1055        }
1056
1057        case OMX_QcomIndexPortDefn:
1058        {
1059            OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam =
1060                (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData;
1061            DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn");
1062            if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN)
1063            {
1064                if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1065                        pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1066                {
1067                    m_use_input_pmem = OMX_TRUE;
1068                }
1069                else
1070                {
1071                    m_use_input_pmem = OMX_FALSE;
1072                }
1073            }
1074            else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1075            {
1076                if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1077                        pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1078                {
1079                    m_use_output_pmem = OMX_TRUE;
1080                }
1081                else
1082                {
1083                    m_use_output_pmem = OMX_FALSE;
1084                }
1085            }
1086            else
1087            {
1088                DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn");
1089                RETURN(OMX_ErrorBadPortIndex);
1090            }
1091            break;
1092        }
1093
1094        case OMX_IndexParamVideoErrorCorrection:
1095        {
1096            DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
1097            OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
1098                (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1099
1100            /* HEC */
1101            if (m_codec == SWVENC_CODEC_MPEG4)
1102            {
1103               Prop.id = SWVENC_PROPERTY_ID_MPEG4_HEC;
1104               Prop.info.mpeg4_hec = pParam->bEnableHEC;
1105
1106               Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1107               if (Ret != SWVENC_S_SUCCESS)
1108               {
1109                  DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1110                    __FUNCTION__, Ret);
1111                  RETURN(OMX_ErrorUndefined);
1112               }
1113
1114               /* Data partitioning */
1115               Prop.id = SWVENC_PROPERTY_ID_MPEG4_DP;
1116               Prop.info.mpeg4_dp = pParam->bEnableDataPartitioning;
1117
1118               Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1119               if (Ret != SWVENC_S_SUCCESS)
1120               {
1121                  DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1122                    __FUNCTION__, Ret);
1123                  RETURN(OMX_ErrorUndefined);
1124               }
1125            }
1126
1127            /* RVLC */
1128            if (pParam->bEnableRVLC)
1129            {
1130               DEBUG_PRINT_ERROR("%s, RVLC not support", __FUNCTION__);
1131            }
1132
1133            /* Re-sync Marker */
1134            Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG;
1135            if ( (m_codec != SWVENC_CODEC_H263) && (pParam->bEnableDataPartitioning) )
1136            {
1137               DEBUG_PRINT_ERROR("DataPartioning are not Supported for this codec");
1138               break;
1139            }
1140            if ( (m_codec != SWVENC_CODEC_H263) && (pParam->nResynchMarkerSpacing) )
1141            {
1142               Prop.info.slice_config.mode = SWVENC_SLICE_MODE_BYTE;
1143               Prop.info.slice_config.size = pParam->nResynchMarkerSpacing;
1144            }
1145            else if ( (SWVENC_CODEC_H263 == m_codec) && (pParam->bEnableResync) )
1146            {
1147               Prop.info.slice_config.mode = SWVENC_SLICE_MODE_GOB;
1148               Prop.info.slice_config.size = 0;
1149               Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1150               if (Ret != SWVENC_S_SUCCESS)
1151               {
1152                  DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1153                    __FUNCTION__, Ret);
1154                  RETURN(OMX_ErrorUndefined);
1155               }
1156            }
1157            else
1158            {
1159               Prop.info.slice_config.mode = SWVENC_SLICE_MODE_OFF;
1160               Prop.info.slice_config.size = 0;
1161            }
1162
1163            memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
1164            break;
1165        }
1166
1167        case OMX_IndexParamVideoIntraRefresh:
1168        {
1169            DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
1170            OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
1171                (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1172
1173            Ret = swvenc_set_intra_refresh(pParam);
1174            if (Ret != SWVENC_S_SUCCESS)
1175            {
1176               DEBUG_PRINT_ERROR("%s, swvenc_set_intra_refresh failed (%d)",
1177                 __FUNCTION__, Ret);
1178               RETURN(OMX_ErrorUnsupportedSetting);
1179            }
1180
1181            memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
1182            break;
1183        }
1184
1185        case OMX_QcomIndexParamVideoMetaBufferMode:
1186        {
1187            StoreMetaDataInBuffersParams *pParam =
1188                (StoreMetaDataInBuffersParams*)paramData;
1189            DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
1190                    "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData);
1191
1192            if (pParam->nPortIndex == PORT_INDEX_IN)
1193            {
1194                if (pParam->bStoreMetaData != meta_mode_enable)
1195                {
1196                    meta_mode_enable = pParam->bStoreMetaData;
1197                    if (!meta_mode_enable)
1198                    {
1199                        Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
1200                                 &m_sOutPortDef.nBufferCountActual,
1201                                 &m_sOutPortDef.nBufferSize,
1202                                 &m_sOutPortDef.nBufferAlignment,
1203                                 m_sOutPortDef.nPortIndex);
1204                        if (Ret != SWVENC_S_SUCCESS)
1205                        {
1206                           DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
1207                              Ret);
1208                           eRet = OMX_ErrorUndefined;
1209                           break;
1210                        }
1211                    }
1212                }
1213            }
1214            else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session)
1215            {
1216                if (pParam->bStoreMetaData != meta_mode_enable)
1217                {
1218                    meta_mode_enable = pParam->bStoreMetaData;
1219                }
1220            }
1221            else
1222            {
1223                if (pParam->bStoreMetaData)
1224                {
1225                    DEBUG_PRINT_ERROR("set_parameter: metamode is "
1226                            "valid for input port only");
1227                    eRet = OMX_ErrorUnsupportedIndex;
1228                }
1229            }
1230        }
1231        break;
1232
1233        case OMX_QcomIndexParamIndexExtraDataType:
1234        {
1235            DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
1236            QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1237            OMX_U32 mask = 0;
1238
1239            if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
1240            {
1241                if (pParam->nPortIndex == PORT_INDEX_OUT)
1242                {
1243                    mask = VEN_EXTRADATA_SLICEINFO;
1244
1245                    DEBUG_PRINT_HIGH("SliceInfo extradata %s",
1246                            ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1247                }
1248                else
1249                {
1250                    DEBUG_PRINT_ERROR("set_parameter: Slice information is "
1251                            "valid for output port only");
1252                    eRet = OMX_ErrorUnsupportedIndex;
1253                    break;
1254                }
1255            }
1256            else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo)
1257            {
1258                if (pParam->nPortIndex == PORT_INDEX_OUT)
1259                {
1260                    mask = VEN_EXTRADATA_MBINFO;
1261
1262                    DEBUG_PRINT_HIGH("MBInfo extradata %s",
1263                            ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1264                }
1265                else
1266                {
1267                    DEBUG_PRINT_ERROR("set_parameter: MB information is "
1268                            "valid for output port only");
1269                    eRet = OMX_ErrorUnsupportedIndex;
1270                    break;
1271                }
1272            }
1273            else
1274            {
1275                DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)",
1276                        pParam->nIndex);
1277                eRet = OMX_ErrorUnsupportedIndex;
1278                break;
1279            }
1280
1281
1282            if (pParam->bEnabled == OMX_TRUE)
1283            {
1284                m_sExtraData |= mask;
1285            }
1286            else
1287            {
1288                m_sExtraData &= ~mask;
1289            }
1290
1291            #if 0
1292            // TBD: add setprop to swvenc once the support is added
1293            if (handle->venc_set_param((OMX_PTR)!!(m_sExtraData & mask),
1294                        (OMX_INDEXTYPE)pParam->nIndex) != true)
1295            {
1296                DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex);
1297                RETURN(OMX_ErrorUnsupportedSetting);
1298            }
1299            else
1300            #endif
1301            {
1302                m_sOutPortDef.nPortIndex = PORT_INDEX_OUT;
1303                bResult = dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
1304                        &m_sOutPortDef.nBufferCountActual,
1305                        &m_sOutPortDef.nBufferSize,
1306                        m_sOutPortDef.nPortIndex);
1307                if (false == bResult)
1308                {
1309                   DEBUG_PRINT_ERROR("dev_get_buf_req failed");
1310                   eRet = OMX_ErrorUndefined;
1311                   break;
1312                }
1313
1314                DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%u, "
1315                        "count min=%u, buffer size=%u",
1316                        m_sOutPortDef.nBufferCountActual,
1317                        m_sOutPortDef.nBufferCountMin,
1318                        m_sOutPortDef.nBufferSize);
1319            }
1320            break;
1321        }
1322
1323        case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck:
1324        {
1325            QOMX_EXTNINDEX_PARAMTYPE* pParam =
1326                (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1327            if (pParam->nPortIndex == PORT_INDEX_OUT)
1328            {
1329                m_max_allowed_bitrate_check =
1330                    ((pParam->bEnable == OMX_TRUE) ? true : false);
1331                DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s",
1332                        ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled"));
1333            }
1334            else
1335            {
1336                DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck "
1337                        " called on wrong port(%u)", pParam->nPortIndex);
1338                RETURN(OMX_ErrorBadPortIndex);
1339            }
1340            break;
1341        }
1342
1343        case OMX_QcomIndexEnableSliceDeliveryMode:
1344        {
1345            QOMX_EXTNINDEX_PARAMTYPE* pParam =
1346                (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1347            if (pParam->nPortIndex == PORT_INDEX_OUT)
1348            {
1349                //TBD: add setprop to swvenc once the support is added
1350                #if 0
1351                if (!handle->venc_set_param(paramData,
1352                            (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) {
1353                    DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
1354                    RETURN( OMX_ErrorUnsupportedSetting;
1355                }
1356                #endif
1357                {
1358                    DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
1359                    RETURN(OMX_ErrorUnsupportedSetting);
1360                }
1361            }
1362            else
1363            {
1364                DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode "
1365                        "called on wrong port(%u)", pParam->nPortIndex);
1366                RETURN(OMX_ErrorBadPortIndex);
1367            }
1368            break;
1369        }
1370
1371        case OMX_QcomIndexEnableH263PlusPType:
1372        {
1373            QOMX_EXTNINDEX_PARAMTYPE* pParam =
1374                (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1375            DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
1376            if (pParam->nPortIndex == PORT_INDEX_OUT)
1377            {
1378                DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
1379                RETURN(OMX_ErrorUnsupportedSetting);
1380            }
1381            else
1382            {
1383                DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType "
1384                        "called on wrong port(%u)", pParam->nPortIndex);
1385                RETURN(OMX_ErrorBadPortIndex);
1386            }
1387            break;
1388        }
1389
1390        case OMX_QcomIndexParamPeakBitrate:
1391        {
1392            DEBUG_PRINT_ERROR("ERROR: Setting peak bitrate");
1393            RETURN(OMX_ErrorUnsupportedSetting);
1394            break;
1395        }
1396
1397        case QOMX_IndexParamVideoInitialQp:
1398        {
1399            // TBD: applicable to RC-on case only
1400            DEBUG_PRINT_ERROR("ERROR: Setting Initial QP for RC-on case");
1401            RETURN(OMX_ErrorNone);
1402            break;
1403        }
1404
1405
1406        case OMX_QcomIndexParamSetMVSearchrange:
1407        {
1408            DEBUG_PRINT_ERROR("ERROR: Setting Searchrange");
1409            RETURN(OMX_ErrorUnsupportedSetting);
1410            break;
1411        }
1412
1413        default:
1414        {
1415            DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex);
1416            eRet = OMX_ErrorUnsupportedIndex;
1417            break;
1418        }
1419    }
1420
1421    RETURN(eRet);
1422}
1423
1424OMX_ERRORTYPE  omx_venc::set_config
1425(
1426   OMX_IN OMX_HANDLETYPE      hComp,
1427   OMX_IN OMX_INDEXTYPE configIndex,
1428   OMX_IN OMX_PTR        configData
1429)
1430{
1431    ENTER_FUNC();
1432
1433    SWVENC_STATUS SwStatus;
1434
1435    (void)hComp;
1436
1437    if (configData == NULL)
1438    {
1439        DEBUG_PRINT_ERROR("ERROR: param is null");
1440        RETURN(OMX_ErrorBadParameter);
1441    }
1442
1443    if (m_state == OMX_StateInvalid)
1444    {
1445        DEBUG_PRINT_ERROR("ERROR: config called in Invalid state");
1446        RETURN(OMX_ErrorIncorrectStateOperation);
1447    }
1448
1449    switch ((int)configIndex)
1450    {
1451        case OMX_IndexConfigVideoBitrate:
1452        {
1453            OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
1454                reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
1455            DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate);
1456
1457            if (pParam->nPortIndex == PORT_INDEX_OUT)
1458            {
1459                SwStatus = swvenc_set_bit_rate(pParam->nEncodeBitrate);
1460                if (SwStatus != SWVENC_S_SUCCESS)
1461                {
1462                   DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
1463                     __FUNCTION__, SwStatus);
1464                   RETURN(OMX_ErrorUnsupportedSetting);
1465                }
1466
1467                m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
1468                m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
1469                m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
1470            }
1471            else
1472            {
1473                DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1474                RETURN(OMX_ErrorBadPortIndex);
1475            }
1476            break;
1477        }
1478        case OMX_IndexConfigVideoFramerate:
1479        {
1480            OMX_CONFIG_FRAMERATETYPE* pParam =
1481                reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
1482            DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate);
1483
1484            if (pParam->nPortIndex == PORT_INDEX_OUT)
1485            {
1486                SwStatus = swvenc_set_frame_rate(pParam->xEncodeFramerate >> 16);
1487                if (SwStatus != SWVENC_S_SUCCESS)
1488                {
1489                   DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
1490                     __FUNCTION__, SwStatus);
1491                   RETURN(OMX_ErrorUnsupportedSetting);
1492                }
1493
1494                m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
1495                m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
1496                m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
1497            }
1498            else
1499            {
1500                DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1501                RETURN(OMX_ErrorBadPortIndex);
1502            }
1503            break;
1504        }
1505        case QOMX_IndexConfigVideoIntraperiod:
1506        {
1507            QOMX_VIDEO_INTRAPERIODTYPE* pParam =
1508                reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
1509            DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod");
1510
1511            if (pParam->nPortIndex == PORT_INDEX_OUT)
1512            {
1513                if (pParam->nBFrames > 0)
1514                {
1515                    DEBUG_PRINT_ERROR("B frames not supported");
1516                    RETURN(OMX_ErrorUnsupportedSetting);
1517                }
1518
1519                DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
1520                        m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames,
1521                        pParam->nPFrames, pParam->nBFrames);
1522                if (m_sIntraperiod.nBFrames != pParam->nBFrames)
1523                {
1524                    DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported");
1525                    RETURN(OMX_ErrorUnsupportedSetting);
1526                }
1527
1528                /* set the intra period */
1529                SwStatus = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
1530                if (SwStatus != SWVENC_S_SUCCESS)
1531                {
1532                   DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
1533                     __FUNCTION__, SwStatus);
1534                   RETURN(OMX_ErrorUnsupportedSetting);
1535                }
1536
1537                m_sIntraperiod.nPFrames = pParam->nPFrames;
1538                m_sIntraperiod.nBFrames = pParam->nBFrames;
1539                m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod;
1540
1541                if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
1542                {
1543                    m_sParamMPEG4.nPFrames = pParam->nPFrames;
1544                    if (m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple)
1545                    {
1546                        m_sParamMPEG4.nBFrames = pParam->nBFrames;
1547                    }
1548                    else
1549                    {
1550                        m_sParamMPEG4.nBFrames = 0;
1551                    }
1552                }
1553                else if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263)
1554                {
1555                    m_sParamH263.nPFrames = pParam->nPFrames;
1556                }
1557            }
1558            else
1559            {
1560                DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
1561                RETURN(OMX_ErrorBadPortIndex);
1562            }
1563
1564            break;
1565        }
1566        case OMX_IndexConfigVideoIntraVOPRefresh:
1567        {
1568            OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
1569                reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
1570            DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh");
1571
1572            if (pParam->nPortIndex == PORT_INDEX_OUT)
1573            {
1574
1575                SWVENC_PROPERTY Prop;
1576
1577                Prop.id = SWVENC_PROPERTY_ID_IFRAME_REQUEST;
1578
1579                SwStatus = swvenc_setproperty(m_hSwVenc, &Prop);
1580                if (SwStatus != SWVENC_S_SUCCESS)
1581                {
1582                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1583                     __FUNCTION__, SwStatus);
1584                   RETURN(OMX_ErrorUnsupportedSetting);
1585                }
1586
1587                m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
1588            }
1589            else
1590            {
1591                DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1592                RETURN(OMX_ErrorBadPortIndex);
1593            }
1594            break;
1595        }
1596        case OMX_IndexConfigCommonRotate:
1597        {
1598            DEBUG_PRINT_ERROR("ERROR: OMX_IndexConfigCommonRotate not supported");
1599            RETURN(OMX_ErrorUnsupportedSetting);
1600            break;
1601        }
1602        default:
1603            DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
1604            RETURN(OMX_ErrorUnsupportedSetting);
1605            break;
1606    }
1607
1608    EXIT_FUNC();
1609
1610    RETURN(OMX_ErrorNone);
1611}
1612
1613OMX_ERRORTYPE  omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
1614{
1615    ENTER_FUNC();
1616
1617    OMX_U32 i = 0;
1618    DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()");
1619
1620    (void)hComp;
1621
1622    if (OMX_StateLoaded != m_state)
1623    {
1624        DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",
1625                m_state);
1626    }
1627    if (m_out_mem_ptr)
1628    {
1629        DEBUG_PRINT_LOW("Freeing the Output Memory");
1630        for (i=0; i< m_sOutPortDef.nBufferCountActual; i++ )
1631        {
1632            free_output_buffer (&m_out_mem_ptr[i]);
1633        }
1634        free(m_out_mem_ptr);
1635        m_out_mem_ptr = NULL;
1636    }
1637
1638    /* Check if the input buffers have to be cleaned up */
1639    if ( m_inp_mem_ptr && !meta_mode_enable )
1640    {
1641        DEBUG_PRINT_LOW("Freeing the Input Memory");
1642        for (i=0; i<m_sInPortDef.nBufferCountActual; i++)
1643        {
1644            free_input_buffer (&m_inp_mem_ptr[i]);
1645        }
1646
1647        free(m_inp_mem_ptr);
1648        m_inp_mem_ptr = NULL;
1649    }
1650
1651    /* Reset counters in msg queues */
1652    m_ftb_q.m_size=0;
1653    m_cmd_q.m_size=0;
1654    m_etb_q.m_size=0;
1655    m_ftb_q.m_read = m_ftb_q.m_write =0;
1656    m_cmd_q.m_read = m_cmd_q.m_write =0;
1657    m_etb_q.m_read = m_etb_q.m_write =0;
1658
1659    /* Clear the strong reference */
1660    DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()");
1661    m_heap_ptr.clear();
1662
1663    DEBUG_PRINT_HIGH("Calling swvenc_deinit()");
1664    swvenc_deinit(m_hSwVenc);
1665
1666    DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit");
1667
1668    RETURN(OMX_ErrorNone);
1669}
1670
1671OMX_U32 omx_venc::dev_stop(void)
1672{
1673    ENTER_FUNC();
1674
1675    SWVENC_STATUS Ret;
1676
1677    if (false == m_stopped)
1678    {
1679       Ret = swvenc_stop(m_hSwVenc);
1680       if (Ret != SWVENC_S_SUCCESS)
1681       {
1682          DEBUG_PRINT_ERROR("%s, swvenc_stop failed (%d)",
1683            __FUNCTION__, Ret);
1684          RETURN(-1);
1685       }
1686       set_format = false;
1687       m_stopped = true;
1688
1689       /* post STOP_DONE event as start is synchronus */
1690       post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_STOP_DONE);
1691    }
1692
1693    RETURN(0);
1694}
1695
1696OMX_U32 omx_venc::dev_pause(void)
1697{
1698    ENTER_FUNC();
1699    // nothing to be done for sw encoder
1700
1701    RETURN(true);
1702}
1703
1704OMX_U32 omx_venc::dev_resume(void)
1705{
1706    ENTER_FUNC();
1707    // nothing to be done for sw encoder
1708
1709    RETURN(true);
1710}
1711
1712OMX_U32 omx_venc::dev_start(void)
1713{
1714   ENTER_FUNC();
1715   SWVENC_STATUS Ret;
1716   Ret = swvenc_start(m_hSwVenc);
1717   if (Ret != SWVENC_S_SUCCESS)
1718   {
1719      DEBUG_PRINT_ERROR("%s, swvenc_start failed (%d)",
1720        __FUNCTION__, Ret);
1721      RETURN(-1);
1722   }
1723
1724   m_stopped = false;
1725
1726   RETURN(0);
1727}
1728
1729OMX_U32 omx_venc::dev_flush(unsigned port)
1730{
1731   ENTER_FUNC();
1732   SWVENC_STATUS Ret;
1733
1734   (void)port;
1735   Ret = swvenc_flush(m_hSwVenc);
1736   if (Ret != SWVENC_S_SUCCESS)
1737   {
1738      DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
1739        __FUNCTION__, Ret);
1740      RETURN(-1);
1741   }
1742
1743   RETURN(0);
1744}
1745
1746OMX_U32 omx_venc::dev_start_done(void)
1747{
1748   ENTER_FUNC();
1749
1750   /* post START_DONE event as start is synchronus */
1751   post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_START_DONE);
1752
1753   RETURN(0);
1754}
1755
1756OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid)
1757{
1758    ENTER_FUNC();
1759
1760    // nothing to be done for sw encoder
1761    (void)tid;
1762
1763    RETURN(true);
1764}
1765
1766bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index)
1767{
1768    ENTER_FUNC();
1769
1770    (void)buf_addr;
1771    (void)port;
1772    (void)index;
1773
1774    RETURN(true);
1775}
1776
1777bool omx_venc::dev_free_buf(void *buf_addr,unsigned port)
1778{
1779    ENTER_FUNC();
1780
1781    (void)buf_addr;
1782    (void)port;
1783
1784    RETURN(true);
1785}
1786
1787bool omx_venc::dev_empty_buf
1788(
1789    void *buffer,
1790    void *pmem_data_buf,
1791    unsigned index,
1792    unsigned fd
1793)
1794{
1795    ENTER_FUNC();
1796
1797    SWVENC_STATUS Ret;
1798    SWVENC_IPBUFFER ipbuffer;
1799    OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1800    unsigned int size = 0, filled_length, offset = 0;
1801    SWVENC_COLOR_FORMAT color_format;
1802    SWVENC_PROPERTY prop;
1803
1804    (void)pmem_data_buf;
1805    (void)index;
1806
1807    if (meta_mode_enable)
1808    {
1809        LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
1810        meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
1811        if(m_sInPortDef.format.video.eColorFormat == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
1812        {
1813            DEBUG_PRINT_LOW("dev_empty_buf: color_format is QOMX_COLOR_FormatAndroidOpaque");
1814            set_format = true;
1815        }
1816        if(!meta_buf)
1817        {
1818            if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS))
1819            {
1820                ipbuffer.p_buffer= bufhdr->pBuffer;
1821                ipbuffer.size = bufhdr->nAllocLen;
1822                ipbuffer.filled_length = bufhdr->nFilledLen;
1823                DEBUG_PRINT_LOW("dev_empty_buf: empty EOS buffer");
1824            }
1825            else
1826            {
1827                return false;
1828            }
1829        }
1830        else
1831        {
1832            if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
1833            {
1834                offset = meta_buf->meta_handle->data[1];
1835                size = meta_buf->meta_handle->data[2];
1836                if (set_format && (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 5))
1837                {
1838                    m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)meta_buf->meta_handle->data[5];
1839                }
1840                ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
1841                if (ipbuffer.p_buffer == MAP_FAILED)
1842                {
1843                    DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
1844                    RETURN(OMX_ErrorBadParameter);
1845                }
1846                ipbuffer.size = size;
1847                ipbuffer.filled_length = size;
1848            }
1849            else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
1850            {
1851                VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
1852                private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
1853                size = handle->size;
1854                if(set_format)
1855                {
1856                    DEBUG_PRINT_LOW("color format = 0x%x",handle->format);
1857                    if (((OMX_COLOR_FORMATTYPE)handle->format) != m_sInPortFormat.eColorFormat)
1858                    {
1859                        if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
1860                        {
1861                            m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
1862                                QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1863                        }
1864                        else
1865                        {
1866                            DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat 0x%x invalid",
1867                                              __FUNCTION__,handle->format);
1868                            RETURN(OMX_ErrorBadParameter);
1869                        }
1870                    }
1871                }
1872                ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
1873                if (ipbuffer.p_buffer == MAP_FAILED)
1874                {
1875                    DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
1876                    RETURN(OMX_ErrorBadParameter);
1877                }
1878                ipbuffer.size = size;
1879                ipbuffer.filled_length = size;
1880            }
1881            else
1882            {
1883                //handles the use case for surface encode
1884                ipbuffer.p_buffer = bufhdr->pBuffer;
1885                ipbuffer.size = bufhdr->nAllocLen;
1886                ipbuffer.filled_length = bufhdr->nFilledLen;
1887            }
1888            if (set_format)
1889            {
1890                set_format = false;
1891                m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
1892                Ret = swvenc_set_color_format(m_sInPortFormat.eColorFormat);
1893                if (Ret != SWVENC_S_SUCCESS)
1894                {
1895                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1896                        __FUNCTION__, Ret);
1897                    RETURN(OMX_ErrorUnsupportedSetting);
1898                }
1899            }
1900        }
1901    }
1902    else
1903    {
1904        ipbuffer.p_buffer = bufhdr->pBuffer;
1905        ipbuffer.size = bufhdr->nAllocLen;
1906        ipbuffer.filled_length = bufhdr->nFilledLen;
1907    }
1908    ipbuffer.flags = 0;
1909    if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
1910    {
1911      ipbuffer.flags |= SWVENC_FLAG_EOS;
1912    }
1913    ipbuffer.timestamp = bufhdr->nTimeStamp;
1914    ipbuffer.p_client_data = (unsigned char *)bufhdr;
1915
1916    DEBUG_PRINT_LOW("ETB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
1917      ipbuffer.p_buffer,
1918      ipbuffer.size,
1919      ipbuffer.filled_length,
1920      (unsigned int)ipbuffer.flags,
1921      ipbuffer.timestamp,
1922      ipbuffer.p_client_data);
1923
1924    Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
1925    if (Ret != SWVENC_S_SUCCESS)
1926    {
1927       DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
1928         __FUNCTION__, Ret);
1929       RETURN(false);
1930    }
1931
1932    if (m_debug.in_buffer_log)
1933    {
1934       swvenc_input_log_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length);
1935    }
1936
1937    RETURN(true);
1938}
1939
1940bool omx_venc::dev_fill_buf
1941(
1942    void *buffer,
1943    void *pmem_data_buf,
1944    unsigned index,
1945    unsigned fd
1946)
1947{
1948    ENTER_FUNC();
1949
1950    SWVENC_STATUS Ret;
1951
1952    SWVENC_OPBUFFER opbuffer;
1953    OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1954
1955    (void)pmem_data_buf;
1956    (void)index;
1957    (void)fd;
1958
1959    opbuffer.p_buffer = bufhdr->pBuffer;
1960    opbuffer.size = bufhdr->nAllocLen;
1961    opbuffer.filled_length = bufhdr->nFilledLen;
1962    opbuffer.flags = bufhdr->nFlags;
1963    opbuffer.p_client_data = (unsigned char *)bufhdr;
1964
1965    DEBUG_PRINT_LOW("FTB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
1966      opbuffer.p_buffer,
1967      opbuffer.size,
1968      opbuffer.filled_length,
1969      opbuffer.flags,
1970      opbuffer.timestamp,
1971      opbuffer.p_client_data);
1972
1973    if ( false == m_bSeqHdrRequested)
1974    {
1975      if (dev_get_seq_hdr(opbuffer.p_buffer, opbuffer.size, &opbuffer.filled_length) == 0)
1976      {
1977         bufhdr->nFilledLen = opbuffer.filled_length;
1978         bufhdr->nOffset = 0;
1979         bufhdr->nTimeStamp = 0;
1980         bufhdr->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
1981
1982         DEBUG_PRINT_LOW("sending FBD with codec config");
1983         m_bSeqHdrRequested = true;
1984         post_event ((unsigned long)bufhdr,0,OMX_COMPONENT_GENERATE_FBD);
1985      }
1986      else
1987      {
1988         DEBUG_PRINT_ERROR("ERROR: couldn't get sequence header");
1989         post_event(OMX_EventError,OMX_ErrorUndefined,OMX_COMPONENT_GENERATE_EVENT);
1990      }
1991    }
1992    else
1993    {
1994       Ret = swvenc_fillthisbuffer(m_hSwVenc, &opbuffer);
1995       if (Ret != SWVENC_S_SUCCESS)
1996       {
1997          DEBUG_PRINT_ERROR("%s, swvenc_fillthisbuffer failed (%d)",
1998            __FUNCTION__, Ret);
1999          RETURN(false);
2000       }
2001    }
2002
2003    RETURN(true);
2004}
2005
2006bool omx_venc::dev_get_seq_hdr
2007(
2008   void *buffer,
2009   unsigned size,
2010   unsigned *hdrlen
2011)
2012{
2013   ENTER_FUNC();
2014
2015   SWVENC_STATUS Ret;
2016   SWVENC_OPBUFFER Buffer;
2017
2018   Buffer.p_buffer = (unsigned char*) buffer;
2019   Buffer.size = size;
2020
2021   Ret = swvenc_getsequenceheader(m_hSwVenc, &Buffer);
2022   if (Ret != SWVENC_S_SUCCESS)
2023   {
2024      DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
2025        __FUNCTION__, Ret);
2026      RETURN(-1);
2027   }
2028
2029   *hdrlen = Buffer.filled_length;
2030
2031   RETURN(0);
2032}
2033
2034bool omx_venc::dev_get_capability_ltrcount
2035(
2036   OMX_U32 *min,
2037   OMX_U32 *max,
2038   OMX_U32 *step_size
2039)
2040{
2041    ENTER_FUNC();
2042
2043    (void)min;
2044    (void)max;
2045    (void)step_size;
2046
2047    DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported");
2048
2049    RETURN(false);
2050}
2051
2052bool omx_venc::dev_get_performance_level(OMX_U32 *perflevel)
2053{
2054    ENTER_FUNC();
2055
2056    (void)perflevel;
2057    DEBUG_PRINT_ERROR("Get performance level is not supported");
2058
2059    RETURN(false);
2060}
2061
2062bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled)
2063{
2064    ENTER_FUNC();
2065
2066    (void)enabled;
2067    DEBUG_PRINT_ERROR("Get vui timing information is not supported");
2068
2069    RETURN(false);
2070}
2071
2072bool omx_venc::dev_get_vqzip_sei_info(OMX_U32 *enabled)
2073{
2074    ENTER_FUNC();
2075
2076    (void)enabled;
2077    DEBUG_PRINT_ERROR("Get vqzip sei info is not supported");
2078
2079    RETURN(false);
2080}
2081
2082bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
2083{
2084    //TBD: store the peak bitrate in class and return here;
2085    ENTER_FUNC();
2086
2087    (void)peakbitrate;
2088    DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
2089
2090    RETURN(false);
2091}
2092
2093bool omx_venc::dev_get_batch_size(OMX_U32 *size)
2094{
2095    ENTER_FUNC();
2096
2097    (void)size;
2098
2099    DEBUG_PRINT_ERROR("Get batch size is not supported");
2100
2101    RETURN(false);
2102}
2103
2104bool omx_venc::dev_loaded_start()
2105{
2106   ENTER_FUNC();
2107   RETURN(true);
2108}
2109
2110bool omx_venc::dev_loaded_stop()
2111{
2112   ENTER_FUNC();
2113   RETURN(true);
2114}
2115
2116bool omx_venc::dev_loaded_start_done()
2117{
2118   ENTER_FUNC();
2119   RETURN(true);
2120}
2121
2122bool omx_venc::dev_loaded_stop_done()
2123{
2124   ENTER_FUNC();
2125   RETURN(true);
2126}
2127
2128bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count,
2129        OMX_U32 *actual_buff_count,
2130        OMX_U32 *buff_size,
2131        OMX_U32 port)
2132{
2133   ENTER_FUNC();
2134
2135   bool bRet = true;
2136   OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2137
2138   if (PORT_INDEX_IN == port)
2139   {
2140     PortDef = &m_sInPortDef;
2141   }
2142   else if (PORT_INDEX_OUT == port)
2143   {
2144     PortDef = &m_sOutPortDef;
2145   }
2146   else
2147   {
2148     DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2149     bRet = false;
2150   }
2151
2152   if (true == bRet)
2153   {
2154      *min_buff_count = PortDef->nBufferCountMin;
2155      *actual_buff_count = PortDef->nBufferCountActual;
2156      *buff_size = PortDef->nBufferSize;
2157   }
2158
2159   RETURN(true);
2160}
2161
2162bool omx_venc::dev_set_buf_req
2163(
2164   OMX_U32 const *min_buff_count,
2165   OMX_U32 const *actual_buff_count,
2166   OMX_U32 const *buff_size,
2167   OMX_U32 port
2168)
2169{
2170   ENTER_FUNC();
2171
2172   SWVENC_STATUS Ret;
2173   OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2174
2175   (void)min_buff_count;
2176   if (PORT_INDEX_IN == port)
2177   {
2178     PortDef = &m_sInPortDef;
2179   }
2180   else if (PORT_INDEX_OUT == port)
2181   {
2182     PortDef = &m_sOutPortDef;
2183   }
2184   else
2185   {
2186     DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2187     RETURN(false);
2188   }
2189
2190   if (*actual_buff_count < PortDef->nBufferCountMin)
2191   {
2192      DEBUG_PRINT_ERROR("ERROR: %s, (actual,min) buffer count (%d, %d)",
2193         __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2194      RETURN(false);
2195   }
2196   if (false == meta_mode_enable)
2197   {
2198      if (*buff_size < PortDef->nBufferSize)
2199      {
2200          DEBUG_PRINT_ERROR("ERROR: %s, (new,old) buffer count (%d, %d)",
2201             __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2202          RETURN(false);
2203      }
2204   }
2205
2206   RETURN(true);
2207}
2208
2209bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height)
2210{
2211   ENTER_FUNC();
2212
2213   if ( (width * height < m_capability.min_width *  m_capability.min_height) ||
2214        (width * height > m_capability.max_width *  m_capability.max_height)
2215      )
2216   {
2217       DEBUG_PRINT_ERROR(
2218         "Unsupported Resolution WxH = (%u)x(%u) Supported Range = min (%d)x(%d) - max (%d)x(%d)",
2219         width, height,
2220         m_capability.min_width, m_capability.min_height,
2221         m_capability.max_width, m_capability.max_height);
2222       RETURN(false);
2223   }
2224
2225   RETURN(true);
2226}
2227
2228bool omx_venc::dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer)
2229{
2230   ENTER_FUNC();
2231
2232   (void)buffer;
2233   RETURN(true);
2234}
2235int omx_venc::dev_handle_output_extradata(void *buffer, int fd)
2236{
2237   ENTER_FUNC();
2238
2239   (void)buffer;
2240   (void)fd;
2241
2242   RETURN(true);
2243}
2244
2245int omx_venc::dev_handle_input_extradata(void *buffer, int fd, int index)
2246{
2247   ENTER_FUNC();
2248
2249   (void)buffer;
2250   (void)fd;
2251   (void)index;
2252
2253   RETURN(true);
2254}
2255
2256void omx_venc::dev_set_extradata_cookie(void *buffer)
2257{
2258   ENTER_FUNC();
2259
2260   (void)buffer;
2261}
2262
2263int omx_venc::dev_set_format(int color)
2264{
2265   ENTER_FUNC();
2266
2267   (void)color;
2268
2269   RETURN(true);
2270    //return handle->venc_set_format(color);
2271}
2272
2273bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
2274                OMX_U32 width, OMX_U32 height)
2275{
2276    ENTER_FUNC();
2277
2278    if(secure_session) {
2279        DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
2280        RETURN(OMX_FALSE);
2281    }
2282    return swvenc_color_align(buffer, width,height);
2283}
2284
2285bool omx_venc::is_secure_session()
2286{
2287    ENTER_FUNC();
2288
2289    RETURN(secure_session);
2290}
2291
2292bool omx_venc::dev_get_output_log_flag()
2293{
2294    ENTER_FUNC();
2295
2296    RETURN(m_debug.out_buffer_log == 1);
2297}
2298
2299int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen)
2300{
2301    ENTER_FUNC();
2302
2303    if (m_debug.out_buffer_log && !m_debug.outfile)
2304    {
2305        int size = 0;
2306        int width = m_sInPortDef.format.video.nFrameWidth;
2307        int height = m_sInPortDef.format.video.nFrameHeight;
2308        if(SWVENC_CODEC_MPEG4 == m_codec)
2309        {
2310           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2311              "%s/output_enc_%d_%d_%p.m4v",
2312              m_debug.log_loc, width, height, this);
2313        }
2314        else if(SWVENC_CODEC_H263 == m_codec)
2315        {
2316           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2317              "%s/output_enc_%d_%d_%p.263",
2318              m_debug.log_loc, width, height, this);
2319        }
2320        if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2321        {
2322           DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
2323                              m_debug.outfile_name, size);
2324           RETURN(-1);
2325        }
2326        DEBUG_PRINT_LOW("output filename = %s", m_debug.outfile_name);
2327        m_debug.outfile = fopen(m_debug.outfile_name, "ab");
2328        if (!m_debug.outfile)
2329        {
2330           DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
2331                             m_debug.outfile_name, errno);
2332           m_debug.outfile_name[0] = '\0';
2333           RETURN(-1);
2334        }
2335    }
2336    if (m_debug.outfile && buffer && bufferlen)
2337    {
2338        DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2339        fwrite(buffer, bufferlen, 1, m_debug.outfile);
2340    }
2341
2342    RETURN(0);
2343}
2344
2345int omx_venc::swvenc_input_log_buffers(const char *buffer, int bufferlen)
2346{
2347   int width = m_sInPortDef.format.video.nFrameWidth;
2348   int height = m_sInPortDef.format.video.nFrameHeight;
2349   int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
2350   int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
2351   char *temp = (char*)buffer;
2352
2353   if (!m_debug.infile)
2354   {
2355       int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX,
2356                      "%s/input_enc_%d_%d_%p.yuv",
2357                      m_debug.log_loc, width, height, this);
2358       if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2359       {
2360           DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
2361                              m_debug.infile_name, size);
2362           RETURN(-1);
2363       }
2364       DEBUG_PRINT_LOW("input filename = %s", m_debug.infile_name);
2365       m_debug.infile = fopen (m_debug.infile_name, "ab");
2366       if (!m_debug.infile)
2367       {
2368           DEBUG_PRINT_HIGH("Failed to open input file: %s for logging",
2369              m_debug.infile_name);
2370           m_debug.infile_name[0] = '\0';
2371           RETURN(-1);
2372       }
2373   }
2374   if (m_debug.infile && buffer && bufferlen)
2375   {
2376       DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2377       for (int i = 0; i < height; i++)
2378       {
2379          fwrite(temp, width, 1, m_debug.infile);
2380          temp += stride;
2381       }
2382       temp = (char*)(buffer + (stride * scanlines));
2383       for(int i = 0; i < height/2; i++)
2384       {
2385          fwrite(temp, width, 1, m_debug.infile);
2386          temp += stride;
2387      }
2388   }
2389
2390   RETURN(0);
2391}
2392
2393int omx_venc::dev_extradata_log_buffers(char *buffer)
2394{
2395   ENTER_FUNC();
2396
2397   (void)buffer;
2398
2399   RETURN(true);
2400    //return handle->venc_extradata_log_buffers(buffer);
2401}
2402
2403SWVENC_STATUS omx_venc::swvenc_get_buffer_req
2404(
2405   OMX_U32 *min_buff_count,
2406   OMX_U32 *actual_buff_count,
2407   OMX_U32 *buff_size,
2408   OMX_U32 *buff_alignment,
2409   OMX_U32 port
2410)
2411{
2412    ENTER_FUNC();
2413
2414    SWVENC_PROPERTY Prop;
2415    SWVENC_STATUS Ret;
2416    OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2417
2418    Prop.id = SWVENC_PROPERTY_ID_BUFFER_REQ;
2419    if (PORT_INDEX_IN == port)
2420    {
2421      Prop.info.buffer_req.type = SWVENC_BUFFER_INPUT;
2422    }
2423    else if (PORT_INDEX_OUT == port)
2424    {
2425      Prop.info.buffer_req.type = SWVENC_BUFFER_OUTPUT;
2426    }
2427    else
2428    {
2429      DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2430      RETURN(SWVENC_S_INVALID_PARAMETERS);
2431    }
2432
2433    Ret = swvenc_getproperty(m_hSwVenc, &Prop);
2434    if (Ret != SWVENC_S_SUCCESS)
2435    {
2436       DEBUG_PRINT_ERROR("ERROR: %s, swvenc_setproperty failed (%d)", __FUNCTION__,
2437          Ret);
2438       RETURN(SWVENC_S_INVALID_PARAMETERS);
2439    }
2440
2441    *buff_size = Prop.info.buffer_req.size;
2442    *min_buff_count = Prop.info.buffer_req.mincount;
2443    *actual_buff_count = Prop.info.buffer_req.mincount;
2444    *buff_alignment = Prop.info.buffer_req.alignment;
2445
2446    RETURN(Ret);
2447}
2448
2449SWVENC_STATUS omx_venc::swvenc_empty_buffer_done_cb
2450(
2451    SWVENC_HANDLE    swvenc,
2452    SWVENC_IPBUFFER *p_ipbuffer,
2453    void            *p_client
2454)
2455{
2456    ENTER_FUNC();
2457
2458    (void)swvenc;
2459    SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
2460    omx_venc *omx = reinterpret_cast<omx_venc*>(p_client);
2461
2462    if (p_ipbuffer == NULL)
2463    {
2464        eRet = SWVENC_S_FAILURE;
2465    }
2466    else
2467    {
2468        omx->swvenc_empty_buffer_done(p_ipbuffer);
2469    }
2470    return eRet;
2471}
2472
2473SWVENC_STATUS omx_venc::swvenc_empty_buffer_done
2474(
2475    SWVENC_IPBUFFER *p_ipbuffer
2476)
2477{
2478    SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
2479    OMX_ERRORTYPE error = OMX_ErrorNone;
2480    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
2481
2482    //omx_video *omx = reinterpret_cast<omx_video*>(p_client);
2483    omxhdr = (OMX_BUFFERHEADERTYPE*)p_ipbuffer->p_client_data;
2484
2485    DEBUG_PRINT_LOW("EBD: clientData (%p)", p_ipbuffer->p_client_data);
2486
2487    if ( (omxhdr == NULL) ||
2488         ( ((OMX_U32)(omxhdr - m_inp_mem_ptr) >m_sInPortDef.nBufferCountActual) &&
2489           ((OMX_U32)(omxhdr - meta_buffer_hdr) >m_sInPortDef.nBufferCountActual)
2490         )
2491       )
2492    {
2493        omxhdr = NULL;
2494        error = OMX_ErrorUndefined;
2495    }
2496
2497    if (omxhdr != NULL)
2498    {
2499        // unmap the input buffer->pBuffer
2500        omx_release_meta_buffer(omxhdr);
2501#ifdef _ANDROID_ICS_
2502        if (meta_mode_enable)
2503        {
2504           LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
2505           unsigned int size = 0;
2506           meta_buf = (LEGACY_CAM_METADATA_TYPE *)omxhdr->pBuffer;
2507           if (meta_buf)
2508           {
2509              if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
2510              {
2511                  size = meta_buf->meta_handle->data[2];
2512              }
2513              else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
2514              {
2515                  VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)omxhdr->pBuffer;
2516                  private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
2517                  size = handle->size;
2518              }
2519           }
2520           int status = munmap(p_ipbuffer->p_buffer, size);
2521           DEBUG_PRINT_HIGH("Unmapped pBuffer <%p> size <%d> status <%d>", p_ipbuffer->p_buffer, size, status);
2522        }
2523#endif
2524        post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_EBD);
2525    }
2526
2527    RETURN(eRet);
2528}
2529
2530SWVENC_STATUS omx_venc::swvenc_fill_buffer_done_cb
2531(
2532    SWVENC_HANDLE    swvenc,
2533    SWVENC_OPBUFFER *p_opbuffer,
2534    void            *p_client
2535)
2536{
2537    ENTER_FUNC();
2538
2539    SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
2540    OMX_ERRORTYPE error = OMX_ErrorNone;
2541    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
2542    omx_video *omx = reinterpret_cast<omx_video*>(p_client);
2543
2544    (void)swvenc;
2545
2546    if (p_opbuffer != NULL)
2547    {
2548        omxhdr = (OMX_BUFFERHEADERTYPE*)p_opbuffer->p_client_data;
2549    }
2550
2551    if ( (p_opbuffer != NULL) &&
2552         ((OMX_U32)(omxhdr - omx->m_out_mem_ptr)  < omx->m_sOutPortDef.nBufferCountActual)
2553       )
2554    {
2555        DEBUG_PRINT_LOW("FBD: clientData (%p) buffer (%p) filled_lengh (%d) flags (0x%x) ts (%lld)",
2556          p_opbuffer->p_client_data,
2557          p_opbuffer->p_buffer,
2558          p_opbuffer->filled_length,
2559          p_opbuffer->flags,
2560          p_opbuffer->timestamp);
2561
2562        if (p_opbuffer->filled_length <=  omxhdr->nAllocLen)
2563        {
2564            omxhdr->pBuffer = p_opbuffer->p_buffer;
2565            omxhdr->nFilledLen = p_opbuffer->filled_length;
2566            omxhdr->nOffset = 0;
2567            omxhdr->nTimeStamp = p_opbuffer->timestamp;
2568            omxhdr->nFlags = 0;
2569            if (SWVENC_FRAME_TYPE_I == p_opbuffer->frame_type)
2570            {
2571               omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2572            }
2573            if (SWVENC_FLAG_EOS & p_opbuffer->flags)
2574            {
2575               omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
2576            }
2577            if(omxhdr->nFilledLen)
2578            {
2579               omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2580            }
2581            DEBUG_PRINT_LOW("o/p flag = 0x%x", omxhdr->nFlags);
2582
2583            /* Use buffer case */
2584            if (omx->output_use_buffer && !omx->m_use_output_pmem)
2585            {
2586                DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
2587                memcpy( omxhdr->pBuffer,
2588                        (p_opbuffer->p_buffer),
2589                        p_opbuffer->filled_length );
2590            }
2591        }
2592        else
2593        {
2594            omxhdr->nFilledLen = 0;
2595        }
2596
2597    }
2598    else
2599    {
2600        omxhdr = NULL;
2601        error = OMX_ErrorUndefined;
2602    }
2603
2604    omx->post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_FBD);
2605
2606    RETURN(eRet);
2607}
2608
2609SWVENC_STATUS omx_venc::swvenc_handle_event_cb
2610(
2611    SWVENC_HANDLE swvenc,
2612    SWVENC_EVENT  event,
2613    void         *p_client
2614)
2615{
2616    ENTER_FUNC();
2617
2618    SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
2619    omx_video *omx = reinterpret_cast<omx_video*>(p_client);
2620
2621    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
2622
2623    (void)swvenc;
2624
2625    if (omx == NULL || p_client == NULL)
2626    {
2627        DEBUG_PRINT_ERROR("ERROR: %s invalid i/p params", __FUNCTION__);
2628        RETURN(SWVENC_S_NULL_POINTER);
2629    }
2630
2631    DEBUG_PRINT_LOW("swvenc_handle_event_cb - event = %d", event);
2632
2633    switch (event)
2634    {
2635        case SWVENC_EVENT_FLUSH_DONE:
2636        {
2637           DEBUG_PRINT_ERROR("SWVENC_EVENT_FLUSH_DONE input_flush_progress %d output_flush_progress %d",
2638            omx->input_flush_progress, omx->output_flush_progress);
2639           if (omx->input_flush_progress)
2640           {
2641               omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
2642                  OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
2643           }
2644           if (omx->output_flush_progress)
2645           {
2646               omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
2647                  OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
2648           }
2649           break;
2650        }
2651
2652        case SWVENC_EVENT_FATAL_ERROR:
2653        {
2654           DEBUG_PRINT_ERROR("ERROR: SWVENC_EVENT_FATAL_ERROR");
2655           omx->omx_report_error();
2656           break;
2657        }
2658
2659        default:
2660            DEBUG_PRINT_HIGH("Unknown event received : %d", event);
2661            break;
2662    }
2663
2664    RETURN(eRet);
2665}
2666
2667SWVENC_STATUS omx_venc::swvenc_set_rc_mode
2668(
2669    OMX_VIDEO_CONTROLRATETYPE eControlRate
2670)
2671{
2672    ENTER_FUNC();
2673
2674    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2675    SWVENC_RC_MODE rc_mode;
2676    SWVENC_PROPERTY Prop;
2677
2678    switch (eControlRate)
2679    {
2680        case OMX_Video_ControlRateDisable:
2681            rc_mode = SWVENC_RC_MODE_NONE;
2682            break;
2683        case OMX_Video_ControlRateVariableSkipFrames:
2684            rc_mode = SWVENC_RC_MODE_VBR_VFR;
2685            break;
2686        case OMX_Video_ControlRateVariable:
2687            rc_mode = SWVENC_RC_MODE_VBR_CFR;
2688            break;
2689        case OMX_Video_ControlRateConstantSkipFrames:
2690            rc_mode = SWVENC_RC_MODE_CBR_VFR;
2691            break;
2692        case OMX_Video_ControlRateConstant:
2693            rc_mode = SWVENC_RC_MODE_CBR_CFR;
2694            break;
2695        default:
2696            DEBUG_PRINT_ERROR("ERROR: UNKNOWN RC MODE");
2697            Ret = SWVENC_S_FAILURE;
2698            break;
2699    }
2700
2701    if (SWVENC_S_SUCCESS == Ret)
2702    {
2703        Prop.id = SWVENC_PROPERTY_ID_RC_MODE;
2704        Prop.info.rc_mode = rc_mode;
2705        Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2706        if (Ret != SWVENC_S_SUCCESS)
2707        {
2708           DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2709             __FUNCTION__, Ret);
2710           RETURN(SWVENC_S_FAILURE);
2711        }
2712    }
2713
2714    RETURN(Ret);
2715}
2716
2717SWVENC_STATUS omx_venc::swvenc_set_profile_level
2718(
2719    OMX_U32 eProfile,
2720    OMX_U32 eLevel
2721)
2722{
2723    ENTER_FUNC();
2724
2725    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2726    SWVENC_PROPERTY Prop;
2727    SWVENC_PROFILE Profile;
2728    SWVENC_LEVEL Level;
2729
2730    /* set the profile */
2731    if (SWVENC_CODEC_MPEG4 == m_codec)
2732    {
2733       switch (eProfile)
2734       {
2735          case OMX_VIDEO_MPEG4ProfileSimple:
2736             Profile.mpeg4 = SWVENC_PROFILE_MPEG4_SIMPLE;
2737             break;
2738          case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
2739             Profile.mpeg4 = SWVENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
2740             break;
2741          default:
2742             DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
2743             Ret = SWVENC_S_FAILURE;
2744             break;
2745       }
2746       switch (eLevel)
2747       {
2748          case OMX_VIDEO_MPEG4Level0:
2749             Level.mpeg4 = SWVENC_LEVEL_MPEG4_0;
2750             break;
2751          case OMX_VIDEO_MPEG4Level0b:
2752             Level.mpeg4 = SWVENC_LEVEL_MPEG4_0B;
2753             break;
2754          case OMX_VIDEO_MPEG4Level1:
2755             Level.mpeg4 = SWVENC_LEVEL_MPEG4_1;
2756             break;
2757          case OMX_VIDEO_MPEG4Level2:
2758             Level.mpeg4 = SWVENC_LEVEL_MPEG4_2;
2759             break;
2760          case OMX_VIDEO_MPEG4Level3:
2761             Level.mpeg4 = SWVENC_LEVEL_MPEG4_3;
2762             break;
2763          case OMX_VIDEO_MPEG4Level4:
2764             Level.mpeg4 = SWVENC_LEVEL_MPEG4_4;
2765             break;
2766          case OMX_VIDEO_MPEG4Level4a:
2767             Level.mpeg4 = SWVENC_LEVEL_MPEG4_4A;
2768             break;
2769          case OMX_VIDEO_MPEG4Level5:
2770             Level.mpeg4 = SWVENC_LEVEL_MPEG4_5;
2771             break;
2772          default:
2773             DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
2774             Ret = SWVENC_S_FAILURE;
2775             break;
2776       }
2777    }
2778    else if (SWVENC_CODEC_H263 == m_codec)
2779    {
2780       switch (eProfile)
2781       {
2782          case OMX_VIDEO_H263ProfileBaseline:
2783             Profile.h263 = SWVENC_PROFILE_H263_BASELINE;
2784             break;
2785          default:
2786             DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
2787             Ret = SWVENC_S_FAILURE;
2788             break;
2789       }
2790       switch (eLevel)
2791       {
2792          case OMX_VIDEO_H263Level10:
2793             Level.h263 = SWVENC_LEVEL_H263_10;
2794             break;
2795          case OMX_VIDEO_H263Level20:
2796             Level.h263 = SWVENC_LEVEL_H263_20;
2797             break;
2798          case OMX_VIDEO_H263Level30:
2799             Level.h263 = SWVENC_LEVEL_H263_30;
2800             break;
2801          case OMX_VIDEO_H263Level40:
2802             Level.h263 = SWVENC_LEVEL_H263_40;
2803             break;
2804          case OMX_VIDEO_H263Level50:
2805             Level.h263 = SWVENC_LEVEL_H263_50;
2806             break;
2807          case OMX_VIDEO_H263Level60:
2808             Level.h263 = SWVENC_LEVEL_H263_60;
2809             break;
2810          case OMX_VIDEO_H263Level70:
2811             Level.h263 = SWVENC_LEVEL_H263_70;
2812             break;
2813          default:
2814             DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
2815             Ret = SWVENC_S_FAILURE;
2816             break;
2817       }
2818    }
2819    else
2820    {
2821      DEBUG_PRINT_ERROR("ERROR: UNSUPPORTED CODEC");
2822      Ret = SWVENC_S_FAILURE;
2823    }
2824
2825    if (SWVENC_S_SUCCESS == Ret)
2826    {
2827       Prop.id = SWVENC_PROPERTY_ID_PROFILE;
2828       Prop.info.profile = Profile;
2829
2830       /* set the profile */
2831       Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2832       if (Ret != SWVENC_S_SUCCESS)
2833       {
2834          DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2835            __FUNCTION__, Ret);
2836          RETURN(SWVENC_S_FAILURE);
2837       }
2838
2839       /* set the level */
2840       Prop.id = SWVENC_PROPERTY_ID_LEVEL;
2841       Prop.info.level = Level;
2842
2843       Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2844       if (Ret != SWVENC_S_SUCCESS)
2845       {
2846          DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2847            __FUNCTION__, Ret);
2848          RETURN(SWVENC_S_FAILURE);
2849       }
2850    }
2851
2852    RETURN(Ret);
2853}
2854
2855SWVENC_STATUS omx_venc::swvenc_set_intra_refresh
2856(
2857    OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh
2858)
2859{
2860   ENTER_FUNC();
2861
2862   SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2863   SWVENC_IR_CONFIG ir_config;
2864   SWVENC_PROPERTY Prop;
2865
2866   switch (IntraRefresh->eRefreshMode)
2867   {
2868      case OMX_VIDEO_IntraRefreshCyclic:
2869        Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC;
2870        break;
2871      case OMX_VIDEO_IntraRefreshAdaptive:
2872         Prop.info.ir_config.mode = SWVENC_IR_MODE_ADAPTIVE;
2873        break;
2874      case OMX_VIDEO_IntraRefreshBoth:
2875         Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC_ADAPTIVE;
2876        break;
2877      case OMX_VIDEO_IntraRefreshRandom:
2878         Prop.info.ir_config.mode = SWVENC_IR_MODE_RANDOM;
2879        break;
2880      default:
2881         DEBUG_PRINT_ERROR("ERROR: UNKNOWN INTRA REFRESH MODE");
2882         Ret = SWVENC_S_FAILURE;
2883         break;
2884   }
2885
2886   if (SWVENC_S_SUCCESS == Ret)
2887   {
2888       Prop.id = SWVENC_PROPERTY_ID_IR_CONFIG;
2889       Prop.info.ir_config.cir_mbs = IntraRefresh->nCirMBs;
2890
2891       Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2892       if (Ret != SWVENC_S_SUCCESS)
2893       {
2894          DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2895            __FUNCTION__, Ret);
2896          Ret = SWVENC_S_FAILURE;
2897       }
2898   }
2899
2900   RETURN(Ret);
2901}
2902
2903SWVENC_STATUS omx_venc::swvenc_set_frame_rate
2904(
2905    OMX_U32 nFrameRate
2906)
2907{
2908   ENTER_FUNC();
2909
2910   SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2911   SWVENC_PROPERTY Prop;
2912
2913   Prop.id = SWVENC_PROPERTY_ID_FRAME_RATE;
2914   Prop.info.frame_rate = nFrameRate;
2915
2916   Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2917   if (Ret != SWVENC_S_SUCCESS)
2918   {
2919      DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2920        __FUNCTION__, Ret);
2921      Ret = SWVENC_S_FAILURE;
2922   }
2923
2924   RETURN(Ret);
2925}
2926
2927SWVENC_STATUS omx_venc::swvenc_set_bit_rate
2928(
2929    OMX_U32 nTargetBitrate
2930)
2931{
2932   ENTER_FUNC();
2933
2934   SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2935   SWVENC_PROPERTY Prop;
2936
2937   Prop.id = SWVENC_PROPERTY_ID_TARGET_BITRATE;
2938   Prop.info.target_bitrate = nTargetBitrate;
2939
2940   Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2941   if (Ret != SWVENC_S_SUCCESS)
2942   {
2943      DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2944        __FUNCTION__, Ret);
2945      Ret = SWVENC_S_FAILURE;
2946   }
2947
2948   RETURN(Ret);
2949}
2950
2951SWVENC_STATUS omx_venc::swvenc_set_intra_period
2952(
2953    OMX_U32 nPFrame,
2954    OMX_U32 nBFrame
2955)
2956{
2957   ENTER_FUNC();
2958
2959   SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
2960   SWVENC_PROPERTY Prop;
2961
2962   Prop.id = SWVENC_PROPERTY_ID_INTRA_PERIOD;
2963   Prop.info.intra_period.pframes = nPFrame;
2964   Prop.info.intra_period.bframes = nBFrame;
2965
2966   Ret = swvenc_setproperty(m_hSwVenc, &Prop);
2967   if (Ret != SWVENC_S_SUCCESS)
2968   {
2969      DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2970        __FUNCTION__, Ret);
2971      Ret = SWVENC_S_FAILURE;
2972   }
2973
2974   RETURN(Ret);
2975}
2976
2977bool omx_venc::swvenc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
2978                        OMX_U32 height)
2979{
2980     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2981            y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2982            uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2983            uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2984            src_chroma_offset = width * height;
2985
2986    if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2987        OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2988        //Do chroma first, so that we can convert it in-place
2989        src_buf += width * height;
2990        dst_buf += y_stride * y_scanlines;
2991        for (int line = height / 2 - 1; line >= 0; --line) {
2992            memmove(dst_buf + line * uv_stride,
2993                    src_buf + line * width,
2994                    width);
2995        }
2996
2997        dst_buf = src_buf = buffer->pBuffer;
2998        //Copy the Y next
2999        for (int line = height - 1; line > 0; --line) {
3000            memmove(dst_buf + line * y_stride,
3001                    src_buf + line * width,
3002                    width);
3003        }
3004    } else {
3005        DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3006                Insufficient bufferLen=%u v/s Required=%u",
3007                (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3008                VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3009        return false;
3010    }
3011
3012    return true;
3013}
3014
3015SWVENC_STATUS omx_venc::swvenc_set_color_format
3016(
3017   OMX_COLOR_FORMATTYPE color_format
3018)
3019{
3020    ENTER_FUNC();
3021    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3022    SWVENC_COLOR_FORMAT swvenc_color_format;
3023    SWVENC_PROPERTY Prop;
3024    if ((color_format == OMX_COLOR_FormatYUV420SemiPlanar) ||
3025         (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
3026    {
3027        swvenc_color_format = SWVENC_COLOR_FORMAT_NV12;
3028    }
3029    else if (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
3030    {
3031        swvenc_color_format = SWVENC_COLOR_FORMAT_NV21;
3032    }
3033    else
3034    {
3035        DEBUG_PRINT_ERROR("%s: color_format %d invalid",__FUNCTION__,color_format);
3036        RETURN(SWVENC_S_FAILURE);
3037    }
3038    /* set the input color format */
3039    Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
3040    Prop.info.color_format = swvenc_color_format;
3041    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3042    if (Ret != SWVENC_S_SUCCESS)
3043    {
3044        DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3045            __FUNCTION__, Ret);
3046        Ret = SWVENC_S_FAILURE;
3047    }
3048    RETURN(Ret);
3049}
3050