1 /*--------------------------------------------------------------------------
2 Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED 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 #include "PlatformConfig.h"
40 
41 /* use GraphicBuffer for rotation */
42 #include <ui/GraphicBufferAllocator.h>
43 #include <gralloc.h>
44 
45 /* def: GET_VT_TIMESTAMP */
46 #include <qdMetaData.h>
47 
48 /*----------------------------------------------------------------------------
49  * Preprocessor Definitions and Constants
50  * -------------------------------------------------------------------------*/
51 #define OMX_SPEC_VERSION 0x00000101
52 #define OMX_INIT_STRUCT(_s_, _name_)             \
53     memset((_s_), 0x0, sizeof(_name_));          \
54     (_s_)->nSize = sizeof(_name_);               \
55     (_s_)->nVersion.nVersion = OMX_SPEC_VERSION
56 
57 #define ENTER_FUNC() DEBUG_PRINT_HIGH("ENTERING: %s",__FUNCTION__)
58 #define EXIT_FUNC()  DEBUG_PRINT_HIGH("EXITING: %s",__FUNCTION__)
59 #define RETURN(x)    EXIT_FUNC(); return x;
60 #undef ALIGN
61 #define ALIGN(value,alignment) (((value) + (alignment-1)) & (~(alignment-1)))
62 
63 #define BUFFER_LOG_LOC "/data/vendor/media"
64 
65 /* factory function executed by the core to create instances */
get_omx_component_factory_fn(void)66 void *get_omx_component_factory_fn(void)
67 {
68     RETURN((new omx_venc));
69 }
70 
omx_venc()71 omx_venc::omx_venc()
72 {
73     ENTER_FUNC();
74 
75     char property_value[PROPERTY_VALUE_MAX] = {0};
76 
77     memset(&m_debug,0,sizeof(m_debug));
78 
79     property_value[0] = '\0';
80     property_get("vendor.vidc.debug.level", property_value, "1");
81     debug_level = atoi(property_value);
82 
83     Platform::Config::getInt32(Platform::vidc_enc_log_in,
84             (int32_t *)&m_debug.in_buffer_log, 0);
85     Platform::Config::getInt32(Platform::vidc_enc_log_out,
86             (int32_t *)&m_debug.out_buffer_log, 0);
87 
88     property_value[0] = '\0';
89     property_get("vendor.vidc.enc.log.in", property_value, "0");
90     m_debug.in_buffer_log = atoi(property_value);
91 
92     property_value[0] = '\0';
93     property_get("vendor.vidc.enc.log.in.rotated", property_value, "0");
94     m_debug.in_buffer_rotated_log = atoi(property_value);
95 
96     property_value[0] = '\0';
97     property_get("vendor.vidc.enc.log.out", property_value, "0");
98     m_debug.out_buffer_log = atoi(property_value);
99 
100     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
101     property_value[0] = '\0';
102     property_get("vendor.vidc.log.loc", property_value, "");
103     if (*property_value)
104     {
105        strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
106     }
107 
108     memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
109     meta_mode_enable = false;
110     memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
111     memset(meta_buffers,0,sizeof(meta_buffers));
112     memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr));
113     mUseProxyColorFormat = false;
114     get_syntaxhdr_enable = false;
115     m_bSeqHdrRequested = false;
116     m_bDimensionsNeedFlip = false;
117     m_bIsRotationSupported = false;
118     m_bIsInFrameSizeSet = false;
119     m_bIsOutFrameSizeSet = false;
120     m_bIsInFlipDone = false;
121     m_bIsOutFlipDone = false;
122     m_bUseAVTimerTimestamps = false;
123     m_bIsIntraperiodSet = false;
124     m_pIpbuffers = nullptr;
125     set_format = false;
126     update_offset = true;
127     m_ubwc_supported = false;
128     EXIT_FUNC();
129 }
130 
~omx_venc()131 omx_venc::~omx_venc()
132 {
133     ENTER_FUNC();
134     get_syntaxhdr_enable = false;
135     EXIT_FUNC();
136 }
137 
component_init(OMX_STRING role)138 OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
139 {
140     ENTER_FUNC();
141 
142     OMX_ERRORTYPE eRet = OMX_ErrorNone;
143     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
144     SWVENC_CALLBACK callBackInfo;
145     OMX_VIDEO_CODINGTYPE codec_type;
146     SWVENC_PROPERTY Prop;
147 
148     strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
149     secure_session = false;
150 
151     if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.mpeg4sw",
152                   OMX_MAX_STRINGNAME_SIZE))
153     {
154         strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
155                 OMX_MAX_STRINGNAME_SIZE);
156         codec_type = OMX_VIDEO_CodingMPEG4;
157         m_codec = SWVENC_CODEC_MPEG4;
158     }
159     else if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.h263sw",
160                   OMX_MAX_STRINGNAME_SIZE))
161     {
162         strlcpy((char *)m_cRole, "video_encoder.h263",\
163                 OMX_MAX_STRINGNAME_SIZE);
164         codec_type = OMX_VIDEO_CodingH263;
165         m_codec = SWVENC_CODEC_H263;
166     }
167     else
168     {
169         DEBUG_PRINT_ERROR("ERROR: Unknown Component");
170         eRet = OMX_ErrorInvalidComponentName;
171         RETURN(eRet);
172     }
173 
174 #ifdef ENABLE_GET_SYNTAX_HDR
175     get_syntaxhdr_enable = true;
176     DEBUG_PRINT_HIGH("Get syntax header enabled");
177 #endif
178 
179     callBackInfo.pfn_empty_buffer_done    = swvenc_empty_buffer_done_cb;
180     callBackInfo.pfn_fill_buffer_done     = swvenc_fill_buffer_done_cb;
181     callBackInfo.pfn_event_notification   = swvenc_handle_event_cb;
182     callBackInfo.p_client                 = (void*)this;
183 
184     SWVENC_STATUS sRet = swvenc_init(&m_hSwVenc, m_codec, &callBackInfo);
185     if (sRet != SWVENC_S_SUCCESS)
186     {
187         DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources",
188          sRet);
189         RETURN(OMX_ErrorInsufficientResources);
190     }
191 
192     sRet = swvenc_check_inst_load(m_hSwVenc);
193     if (sRet != SWVENC_S_SUCCESS)
194     {
195         DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources",
196          sRet);
197         RETURN(OMX_ErrorInsufficientResources);
198     }
199 
200     m_stopped = true;
201 
202     //Intialise the OMX layer variables
203     memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE));
204 
205     OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE);
206     m_sPortParam.nPorts = 0x2;
207     m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN;
208 
209     OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE);
210     m_sPortParam_audio.nPorts = 0;
211     m_sPortParam_audio.nStartPortNumber = 0;
212 
213     OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE);
214     m_sPortParam_img.nPorts = 0;
215     m_sPortParam_img.nStartPortNumber = 0;
216 
217     OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE);
218     m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
219     m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames;
220     m_sParamBitrate.nTargetBitrate = 64000;
221 
222     OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE);
223     m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
224     m_sConfigBitrate.nEncodeBitrate = 64000;
225 
226     OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE);
227     m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
228     m_sConfigFramerate.xEncodeFramerate = 30 << 16;
229 
230     OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE);
231     m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
232     m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE;
233 
234     OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE);
235     m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN;
236     m_sConfigFrameRotation.nRotation = 0;
237 
238     OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
239     m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
240     m_sSessionQuantization.nQpI = 9;
241     m_sSessionQuantization.nQpP = 6;
242     m_sSessionQuantization.nQpB = 2;
243 
244     OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE);
245     m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
246     m_sSessionQPRange.minIQP = 2;
247     m_sSessionQPRange.minPQP = 2;
248     m_sSessionQPRange.minBQP = 2;
249 
250     OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
251     m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
252 
253     OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE);
254     m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
255     m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1;
256 
257     OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
258     m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
259     m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE;
260     m_sErrorCorrection.bEnableHEC = OMX_FALSE;
261     m_sErrorCorrection.bEnableResync = OMX_FALSE;
262     m_sErrorCorrection.bEnableRVLC = OMX_FALSE;
263     m_sErrorCorrection.nResynchMarkerSpacing = 0;
264 
265     OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
266     m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
267     m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax;
268 
269     if (codec_type == OMX_VIDEO_CodingMPEG4)
270     {
271         m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple;
272         m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0;
273     } else if (codec_type == OMX_VIDEO_CodingH263)
274     {
275         m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline;
276         m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10;
277     }
278 
279     /* set the profile and level */
280     Ret = swvenc_set_profile_level(m_sParamProfileLevel.eProfile,
281                 m_sParamProfileLevel.eLevel);
282     if (Ret != SWVENC_S_SUCCESS)
283     {
284        DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
285          __FUNCTION__, Ret);
286        RETURN(OMX_ErrorUndefined);
287     }
288 
289     // Initialize the video parameters for input port
290     OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
291     m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN;
292     m_sInPortDef.bEnabled = OMX_TRUE;
293     m_sInPortDef.bPopulated = OMX_FALSE;
294     m_sInPortDef.eDomain = OMX_PortDomainVideo;
295     m_sInPortDef.eDir = OMX_DirInput;
296     m_sInPortDef.format.video.cMIMEType = (char *)"YUV420";
297     m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
298     m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
299     m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH;
300     m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT;
301     m_sInPortDef.format.video.nBitrate = 64000;
302     m_sInPortDef.format.video.xFramerate = 15 << 16;
303     m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
304         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
305     m_sInPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingUnused;
306 
307     /* set the frame size */
308     Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
309     Prop.info.frame_size.height = m_sInPortDef.format.video.nFrameHeight;
310     Prop.info.frame_size.width  = m_sInPortDef.format.video.nFrameWidth;
311 
312     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
313     if (Ret != SWVENC_S_SUCCESS)
314     {
315        DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
316          __FUNCTION__, Ret);
317        RETURN(OMX_ErrorUnsupportedSetting);
318     }
319 
320     /* set the frame attributes */
321     Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
322     Prop.info.frame_attributes.stride_luma = m_sInPortDef.format.video.nStride;
323     Prop.info.frame_attributes.stride_chroma = m_sInPortDef.format.video.nStride;
324     Prop.info.frame_attributes.offset_luma = 0;
325     Prop.info.frame_attributes.offset_chroma =
326       (m_sInPortDef.format.video.nSliceHeight * m_sInPortDef.format.video.nStride);
327     Prop.info.frame_attributes.size = (Prop.info.frame_attributes.offset_chroma * 3) >> 1;
328 
329     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
330     if (Ret != SWVENC_S_SUCCESS)
331     {
332        DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
333          __FUNCTION__, Ret);
334        RETURN(OMX_ErrorUndefined);
335     }
336 
337     Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
338               &m_sInPortDef.nBufferCountActual,
339               &m_sInPortDef.nBufferSize,
340               &m_sInPortDef.nBufferAlignment,
341               PORT_INDEX_IN);
342     if (Ret != SWVENC_S_SUCCESS)
343     {
344        DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
345           Ret);
346        RETURN(OMX_ErrorUndefined);
347     }
348 
349     // Initialize the video parameters for output port
350     OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
351     m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
352     m_sOutPortDef.bEnabled = OMX_TRUE;
353     m_sOutPortDef.bPopulated = OMX_FALSE;
354     m_sOutPortDef.eDomain = OMX_PortDomainVideo;
355     m_sOutPortDef.eDir = OMX_DirOutput;
356     m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
357     m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
358     m_sOutPortDef.format.video.nBitrate = 64000;
359     m_sOutPortDef.format.video.xFramerate = 15 << 16;
360     m_sOutPortDef.format.video.eColorFormat =  OMX_COLOR_FormatUnused;
361     if (codec_type == OMX_VIDEO_CodingMPEG4)
362     {
363         m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingMPEG4;
364     }
365     else if (codec_type == OMX_VIDEO_CodingH263)
366     {
367         m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingH263;
368     }
369 
370     Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
371               &m_sOutPortDef.nBufferCountActual,
372               &m_sOutPortDef.nBufferSize,
373               &m_sOutPortDef.nBufferAlignment,
374               PORT_INDEX_OUT);
375     if (Ret != SWVENC_S_SUCCESS)
376     {
377        DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
378           Ret);
379        RETURN(OMX_ErrorUndefined);
380     }
381 
382     // Initialize the video color format for input port
383     OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
384     m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN;
385     m_sInPortFormat.nIndex = 0;
386     m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
387         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
388     m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
389 
390     // Initialize the compression format for output port
391     OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
392     m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
393     m_sOutPortFormat.nIndex = 0;
394     m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused;
395     if (codec_type == OMX_VIDEO_CodingMPEG4)
396     {
397         m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingMPEG4;
398     } else if (codec_type == OMX_VIDEO_CodingH263)
399     {
400         m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingH263;
401     }
402 
403     // mandatory Indices for kronos test suite
404     OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE);
405 
406     OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
407     m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN;
408 
409     OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
410     m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
411 
412     OMX_INIT_STRUCT(&m_sConfigQP, OMX_QCOM_VIDEO_CONFIG_QP);
413     m_sConfigQP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
414 
415     // mp4 specific init
416     OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE);
417     m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
418     m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
419     m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0;
420     m_sParamMPEG4.nSliceHeaderSpacing = 0;
421     m_sParamMPEG4.bSVH = OMX_FALSE;
422     m_sParamMPEG4.bGov = OMX_FALSE;
423     // 2 second intra period for default outport fps
424     if(m_sOutPortFormat.xFramerate)
425     m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
426 
427     m_sParamMPEG4.bACPred = OMX_TRUE;
428     // delta = 2 @ 15 fps
429     m_sParamMPEG4.nTimeIncRes = 30;
430     // pframe and iframe
431     m_sParamMPEG4.nAllowedPictureTypes = 2;
432     // number of video packet headers per vop
433     m_sParamMPEG4.nHeaderExtension = 1;
434     m_sParamMPEG4.bReversibleVLC = OMX_FALSE;
435 
436     // h263 specific init
437     OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE);
438     m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
439     // 2 second intra period for default outport fps
440     if(m_sOutPortFormat.xFramerate)
441     m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
442 
443     m_sParamH263.nBFrames = 0;
444     m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline;
445     m_sParamH263.eLevel = OMX_VIDEO_H263Level10;
446     m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE;
447     m_sParamH263.nAllowedPictureTypes = 2;
448     m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE;
449     m_sParamH263.nPictureHeaderRepetition = 0;
450     m_sParamH263.nGOBHeaderInterval = 1;
451 
452     // av-timer init (for ims-vt)
453     OMX_INIT_STRUCT(&m_sParamAVTimerTimestampMode, QOMX_ENABLETYPE);
454     m_sParamAVTimerTimestampMode.bEnable = OMX_FALSE;
455 
456     m_state                   = OMX_StateLoaded;
457     m_sExtraData = 0;
458     //m_sParamConsumerUsage     |= (OMX_U32)GRALLOC_USAGE_SW_READ_OFTEN;
459 
460     if (codec_type == OMX_VIDEO_CodingMPEG4)
461     {
462         m_capability.max_height = OMX_CORE_720P_HEIGHT;
463         m_capability.max_width = OMX_CORE_720P_WIDTH;
464     }
465     else if (codec_type == OMX_VIDEO_CodingH263)
466     {
467         m_capability.max_height = OMX_CORE_FWVGA_HEIGHT;
468         m_capability.max_width = OMX_CORE_FWVGA_WIDTH;
469     }
470 
471     m_capability.min_height = 32;
472     m_capability.min_width = 32;
473 
474     if (eRet == OMX_ErrorNone)
475     {
476         if (pthread_create(&msg_thread_id,0, message_thread_enc, this) < 0)
477         {
478             eRet = OMX_ErrorInsufficientResources;
479             msg_thread_created = false;
480         }
481         else
482         {
483             msg_thread_created = true;
484         }
485     }
486 
487     DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet);
488 
489     EXIT_FUNC();
490 
491     {
492         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
493         init_sw_vendor_extensions(*extStore);
494         mVendorExtensionStore.dumpExtensions((const char *)m_nkind);
495     }
496 
497     RETURN(eRet);
498 }
499 
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)500 OMX_ERRORTYPE  omx_venc::set_parameter
501 (
502     OMX_IN OMX_HANDLETYPE hComp,
503     OMX_IN OMX_INDEXTYPE  paramIndex,
504     OMX_IN OMX_PTR        paramData
505 )
506 {
507     ENTER_FUNC();
508 
509     OMX_ERRORTYPE eRet = OMX_ErrorNone;
510     SWVENC_STATUS Ret  = SWVENC_S_SUCCESS;
511     SWVENC_PROPERTY Prop;
512     bool bResult;
513     unsigned int y_stride, y_scanlines;
514 
515     (void)hComp;
516 
517     if (m_state == OMX_StateInvalid)
518     {
519         DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State");
520         RETURN(OMX_ErrorInvalidState);
521     }
522     if (paramData == NULL)
523     {
524         DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
525         RETURN(OMX_ErrorBadParameter);
526     }
527 
528     /* set_parameter can be called in loaded state or disabled port */
529     if ( (m_state == OMX_StateLoaded) ||
530          (m_sInPortDef.bEnabled == OMX_FALSE) ||
531          (m_sOutPortDef.bEnabled == OMX_FALSE)
532        )
533     {
534         DEBUG_PRINT_LOW("Set Parameter called in valid state");
535     }
536     else
537     {
538         DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
539         RETURN(OMX_ErrorIncorrectStateOperation);
540     }
541 
542     switch ((int)paramIndex)
543     {
544         case OMX_IndexParamPortDefinition:
545         {
546             OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
547             portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
548             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
549                     (int)portDefn->format.video.nFrameHeight,
550                     (int)portDefn->format.video.nFrameWidth);
551 
552             if (PORT_INDEX_IN == portDefn->nPortIndex)
553             {
554                 if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth,
555                             portDefn->format.video.nFrameHeight))
556                 {
557                     DEBUG_PRINT_ERROR("video session not supported");
558                     omx_report_unsupported_setting();
559                     RETURN(OMX_ErrorUnsupportedSetting);
560                 }
561                 DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual);
562                 DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin);
563                 DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize);
564                 if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
565                 {
566                     DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
567                             portDefn->nBufferCountMin, portDefn->nBufferCountActual);
568                     RETURN(OMX_ErrorUnsupportedSetting);
569                 }
570 
571                 // don't update frame size if it's unchanged
572                 if (m_sInPortDef.format.video.nFrameWidth != portDefn->format.video.nFrameWidth
573                         || m_sInPortDef.format.video.nFrameHeight != portDefn->format.video.nFrameHeight) {
574                     /* set the frame size */
575                     Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
576                     Prop.info.frame_size.height = portDefn->format.video.nFrameHeight;
577                     Prop.info.frame_size.width  = portDefn->format.video.nFrameWidth;
578 
579                     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
580                     if (Ret != SWVENC_S_SUCCESS)
581                     {
582                         DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
583                                 __FUNCTION__, Ret);
584                     RETURN(OMX_ErrorUnsupportedSetting);
585                     }
586                 }
587 
588                 /* set the input frame-rate */
589                 if (portDefn->format.video.xFramerate != 0)
590                 {
591                    Ret = swvenc_set_frame_rate(portDefn->format.video.xFramerate >> 16);
592                    if (Ret != SWVENC_S_SUCCESS)
593                    {
594                       DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
595                         __FUNCTION__, Ret);
596                       RETURN(OMX_ErrorUnsupportedSetting);
597                    }
598                 }
599 
600                 /* set the frame attributes */
601                 /*Align stride and scanline to worst case*/
602                 /*------------------------------------------------------------------------------------------
603                 *           [Color Format]                   [Stride Alignment]        [Scanline Alignment]
604                 * QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m       512 or 128                  512 or 32
605                 * OMX_COLOR_FormatYUV420SemiPlanar                 512                         512
606                 * QOMX_COLOR_FormatYVU420SemiPlanar                16                          16
607                 * HAL_PIXEL_FORMAT_NV21_ZSL                        64                          64
608                 *------------------------------------------------------------------------------------------*/
609                 y_stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12,portDefn->format.video.nFrameWidth);
610                 //Slice height doesn't get updated so chroma offset calculation becomes incorrect .
611                 //Using FrameHeight Instead , just for omx-test-app .
612                 y_scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12_ZSL,portDefn->format.video.nFrameHeight);
613                 Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
614                 Prop.info.frame_attributes.stride_luma = y_stride;
615                 Prop.info.frame_attributes.stride_chroma = y_stride;
616                 Prop.info.frame_attributes.offset_luma = 0;
617                 Prop.info.frame_attributes.offset_chroma = y_scanlines * y_stride;
618                 Prop.info.frame_attributes.size = SWVENC_BUFFER_SIZE(COLOR_FMT_NV12_ZSL,
619                                                                      portDefn->format.video.nFrameWidth,
620                                                                      portDefn->format.video.nFrameHeight);
621                 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
622                 if (Ret != SWVENC_S_SUCCESS)
623                 {
624                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
625                      __FUNCTION__, Ret);
626                    RETURN(OMX_ErrorUnsupportedSetting);
627                 }
628 
629                 DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual);
630                 DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin);
631                 DEBUG_PRINT_LOW("i/p previous buffersize = %u", m_sInPortDef.nBufferSize);
632 
633                 memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
634 
635                 /* update the input buffer requirement */
636                 Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
637                         &m_sInPortDef.nBufferCountActual,
638                         &m_sInPortDef.nBufferSize,
639                         &m_sInPortDef.nBufferAlignment,
640                         portDefn->nPortIndex);
641                 if (Ret != SWVENC_S_SUCCESS)
642                 {
643                    DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
644                       Ret);
645                    RETURN(OMX_ErrorUndefined);
646                 }
647 
648                 if (portDefn->nBufferCountActual > m_sInPortDef.nBufferCountActual)
649                 {
650                    m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual;
651                 }
652                 if (portDefn->nBufferSize > m_sInPortDef.nBufferSize)
653                 {
654                    m_sInPortDef.nBufferSize = portDefn->nBufferSize;
655                 }
656 
657                 DEBUG_PRINT_LOW("i/p new actual cnt = %u", m_sInPortDef.nBufferCountActual);
658                 DEBUG_PRINT_LOW("i/p new min cnt = %u", m_sInPortDef.nBufferCountMin);
659                 DEBUG_PRINT_LOW("i/p new buffersize = %u", m_sInPortDef.nBufferSize);
660 
661                 // when rotation is setting before portdefinition, if need flip dimensions
662                 // in port flip will be set here
663                 if (m_bDimensionsNeedFlip && !m_bIsInFlipDone) {
664                     DEBUG_PRINT_HIGH("flip in port dimension(for swcodec) in portdefinition");
665                     OMX_ERRORTYPE err = swvenc_do_flip_inport();
666                     if (err != OMX_ErrorNone) {
667                         DEBUG_PRINT_ERROR("%s, swvenc_do_flip_inport falied (%d)",
668                                 __FUNCTION__, err);
669                         RETURN(err);
670                     }
671                     m_bIsInFlipDone = true;
672                 }
673                 m_bIsInFrameSizeSet = true;
674             }
675             else if (PORT_INDEX_OUT == portDefn->nPortIndex)
676             {
677                 DEBUG_PRINT_LOW("o/p actual cnt requested = %u", portDefn->nBufferCountActual);
678                 DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin);
679                 DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize);
680                 if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
681                 {
682                     DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
683                             portDefn->nBufferCountMin, portDefn->nBufferCountActual);
684                     RETURN(OMX_ErrorUnsupportedSetting);
685                 }
686 
687                 /* set the output bit-rate */
688                 Ret = swvenc_set_bit_rate(portDefn->format.video.nBitrate);
689                 if (Ret != SWVENC_S_SUCCESS)
690                 {
691                    DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
692                      __FUNCTION__, Ret);
693                    RETURN(OMX_ErrorUnsupportedSetting);
694                 }
695 
696                 DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
697                 DEBUG_PRINT_LOW("o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
698                 DEBUG_PRINT_LOW("o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
699 
700                 /* set the buffer requirement */
701                 bResult = dev_set_buf_req(&portDefn->nBufferCountMin,
702                   &portDefn->nBufferCountActual,
703                   &portDefn->nBufferSize,
704                   portDefn->nPortIndex);
705                 if (bResult != true)
706                 {
707                    DEBUG_PRINT_ERROR("%s, dev_set_buf_req failed",
708                      __FUNCTION__);
709                    RETURN(OMX_ErrorUnsupportedSetting);
710                 }
711                 memcpy(&m_sOutPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
712 
713                 /* update the output buffer requirement */
714                 Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
715                         &m_sOutPortDef.nBufferCountActual,
716                         &m_sOutPortDef.nBufferSize,
717                         &m_sOutPortDef.nBufferAlignment,
718                         portDefn->nPortIndex);
719                 if (Ret != SWVENC_S_SUCCESS)
720                 {
721                    DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
722                       Ret);
723                    RETURN(OMX_ErrorUndefined);
724                 }
725 
726                 if (portDefn->nBufferCountActual > m_sOutPortDef.nBufferCountActual)
727                 {
728                    m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual;
729                 }
730                 if (portDefn->nBufferSize > m_sOutPortDef.nBufferSize)
731                 {
732                    m_sOutPortDef.nBufferSize = portDefn->nBufferSize;
733                 }
734 
735                 DEBUG_PRINT_LOW("o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
736                 DEBUG_PRINT_LOW("o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
737                 DEBUG_PRINT_LOW("o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
738                 // when rotation is setting before portdefinition, if need flip dimensions
739                 // out port flip will be set here
740                 if (m_bDimensionsNeedFlip && !m_bIsOutFlipDone) {
741                     DEBUG_PRINT_HIGH("flip out port dimension in portdefinition");
742                     OMX_ERRORTYPE err = swvenc_do_flip_outport();
743                     m_bIsOutFlipDone = true;
744                     DEBUG_PRINT_HIGH("Out Port Definition: rotation (%d), flipped WxH (%d x %d)",
745                             m_sConfigFrameRotation.nRotation,
746                             m_sOutPortDef.format.video.nFrameWidth,
747                             m_sOutPortDef.format.video.nFrameHeight);
748                 }
749                 m_bIsOutFrameSizeSet = true;
750             }
751             else
752             {
753                 DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d",
754                         (int)portDefn->nPortIndex);
755                 eRet = OMX_ErrorBadPortIndex;
756             }
757             m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate;
758             m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate;
759             m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate;
760             break;
761         }
762 
763         case OMX_IndexParamVideoPortFormat:
764         {
765             OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
766                 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
767             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
768                     portFmt->eColorFormat);
769             SWVENC_COLOR_FORMAT color_format;
770 
771             /* set the driver with the corresponding values */
772             if (PORT_INDEX_IN == portFmt->nPortIndex)
773             {
774                 if (portFmt->eColorFormat ==
775                     ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
776                 {
777                     /* meta_mode = 2 (kMetadataBufferTypeGrallocSource) */
778                     m_sInPortFormat.eColorFormat =
779                         (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
780                     color_format = SWVENC_COLOR_FORMAT_NV12;
781                     mUseProxyColorFormat = true;
782                     m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ;
783                 }
784                 else
785                 {
786                     m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
787                     if ((portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) ||
788                         (portFmt->eColorFormat ==
789                          ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
790                     {
791                         color_format = SWVENC_COLOR_FORMAT_NV12;
792                     }
793                     else if (portFmt->eColorFormat ==
794                              ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
795                     {
796                         color_format = SWVENC_COLOR_FORMAT_NV21;
797                     }
798                     else
799                     {
800                         DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat %d invalid",
801                                           __FUNCTION__,
802                                           portFmt->eColorFormat);
803                         RETURN(OMX_ErrorBadParameter);
804                     }
805                     m_input_msg_id = OMX_COMPONENT_GENERATE_ETB;
806                     mUseProxyColorFormat = false;
807                 }
808                 m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
809                 /* set the input color format */
810                 Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
811                 Prop.info.color_format = color_format;
812                 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
813                 if (Ret != SWVENC_S_SUCCESS)
814                 {
815                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
816                      __FUNCTION__, Ret);
817                    RETURN(OMX_ErrorUnsupportedSetting);
818                 }
819 
820                 /* set the input frame-rate */
821                 if (portFmt->xFramerate != 0)
822                 {
823                    Ret = swvenc_set_frame_rate(portFmt->xFramerate >> 16);
824                    if (Ret != SWVENC_S_SUCCESS)
825                    {
826                       DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
827                         __FUNCTION__, Ret);
828                       //RETURN(OMX_ErrorUnsupportedSetting);
829                    }
830                    m_sInPortFormat.xFramerate = portFmt->xFramerate;
831                 }
832             }
833             break;
834         }
835 
836         case OMX_IndexParamVideoInit:
837         {
838             OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
839             DEBUG_PRINT_LOW("Set OMX_IndexParamVideoInit called");
840             break;
841         }
842 
843         case OMX_IndexParamVideoBitrate:
844         {
845             OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
846             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate");
847 
848             /* set the output bit-rate */
849             Ret = swvenc_set_bit_rate(pParam->nTargetBitrate);
850             if (Ret != SWVENC_S_SUCCESS)
851             {
852                DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
853                  __FUNCTION__, Ret);
854                RETURN(OMX_ErrorUnsupportedSetting);
855             }
856 
857             /* set the RC-mode */
858             Ret = swvenc_set_rc_mode(pParam->eControlRate);
859             if (Ret != SWVENC_S_SUCCESS)
860             {
861                DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
862                  __FUNCTION__, Ret);
863                RETURN(OMX_ErrorUnsupportedSetting);
864             }
865 
866             m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate;
867             m_sParamBitrate.eControlRate = pParam->eControlRate;
868             m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate;
869             m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate;
870             m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate;
871             DEBUG_PRINT_LOW("bitrate = %u", m_sOutPortDef.format.video.nBitrate);
872             break;
873         }
874 
875         case OMX_IndexParamVideoMpeg4:
876         {
877             OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
878 
879             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4");
880 
881             if (pParam->nBFrames)
882             {
883                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
884             }
885 
886             /* set the intra period */
887             if (!m_bIsIntraperiodSet)
888             {
889                 DEBUG_PRINT_LOW("pParam->nPFrames : %d", pParam->nPFrames);
890                 Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
891                 if (Ret != SWVENC_S_SUCCESS)
892                 {
893                     DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
894                         __FUNCTION__, Ret);
895                     RETURN(OMX_ErrorUnsupportedSetting);
896                 }
897                 else
898                 {
899                     m_sIntraperiod.nPFrames = pParam->nPFrames;
900                     m_sIntraperiod.nBFrames = pParam->nBFrames;
901                     m_bIsIntraperiodSet = true;
902                 }
903             }
904 
905             /* set profile/level */
906             if (pParam->eProfile && pParam->eLevel)
907             {
908                 DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
909                 Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
910                 if (Ret != SWVENC_S_SUCCESS)
911                 {
912                     DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
913                             __FUNCTION__, Ret);
914                     RETURN(OMX_ErrorUnsupportedSetting);
915                 }
916                 else
917                 {
918                     m_sParamProfileLevel.eProfile = pParam->eProfile;
919                     m_sParamProfileLevel.eLevel = pParam->eLevel;
920                 }
921             }
922 
923             /*set slice config */
924             if (pParam->nSliceHeaderSpacing > 0)
925             {
926                 SWVENC_PROPERTY Prop;
927                 Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG;
928                 Prop.info.slice_config.mode = SWVENC_SLICE_MODE_MB;
929                 Prop.info.slice_config.size = pParam->nSliceHeaderSpacing;
930                 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
931                 if (Ret != SWVENC_S_SUCCESS)
932                 {
933                     DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
934                         __FUNCTION__, Ret);
935                     RETURN(OMX_ErrorUndefined);
936                 }
937                 else
938                 {
939                     m_sParamMPEG4.nSliceHeaderSpacing = pParam->nSliceHeaderSpacing;
940                 }
941             }
942             // NOTE: m_sParamMPEG4.eProfile/eLevel may be overwritten to 0 if client didn't set them
943             memcpy(&m_sParamMPEG4, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
944             break;
945         }
946 
947         case OMX_IndexParamVideoH263:
948         {
949             OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
950 
951             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263");
952 
953             /* set the intra period */
954             if (!m_bIsIntraperiodSet)
955             {
956                 Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
957                 if (Ret != SWVENC_S_SUCCESS)
958                 {
959                     DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
960                         __FUNCTION__, Ret);
961                     RETURN(OMX_ErrorUnsupportedSetting);
962                 }
963                 else
964                 {
965                     m_sIntraperiod.nPFrames = pParam->nPFrames;
966                     m_sIntraperiod.nBFrames = pParam->nBFrames;
967                     m_bIsIntraperiodSet = true;
968                 }
969             }
970 
971             /* set profile/level */
972             if (pParam->eProfile && pParam->eLevel)
973             {
974                 DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
975                 Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
976                 if (Ret != SWVENC_S_SUCCESS)
977                 {
978                     DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
979                             __FUNCTION__, Ret);
980                     RETURN(OMX_ErrorUnsupportedSetting);
981                 }
982                 else
983                 {
984                     m_sParamProfileLevel.eProfile = pParam->eProfile;
985                     m_sParamProfileLevel.eLevel = pParam->eLevel;
986                 }
987             }
988 
989             // NOTE: m_sParamH263.eProfile/eLevel may be overwritten to 0 if client didn't set them
990             memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE));
991             break;
992         }
993 
994         case OMX_IndexParamVideoProfileLevelCurrent:
995         {
996             OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
997 
998             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
999 
1000             /* set the profile and level */
1001             Ret = swvenc_set_profile_level(pParam->eProfile,pParam->eLevel);
1002             if (Ret != SWVENC_S_SUCCESS)
1003             {
1004                DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
1005                  __FUNCTION__, Ret);
1006                RETURN(OMX_ErrorUnsupportedSetting);
1007             }
1008 
1009 
1010             m_sParamProfileLevel.eProfile = pParam->eProfile;
1011             m_sParamProfileLevel.eLevel = pParam->eLevel;
1012 
1013             if (SWVENC_CODEC_MPEG4 == m_codec)
1014             {
1015                 m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile;
1016                 m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel;
1017                 DEBUG_PRINT_LOW("MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
1018                         m_sParamMPEG4.eLevel);
1019             }
1020             else if (SWVENC_CODEC_H263 == m_codec)
1021             {
1022                 m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile;
1023                 m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel;
1024                 DEBUG_PRINT_LOW("H263 profile = %d, level = %d", m_sParamH263.eProfile,
1025                         m_sParamH263.eLevel);
1026             }
1027             break;
1028         }
1029 
1030         case OMX_IndexParamStandardComponentRole:
1031         {
1032             OMX_PARAM_COMPONENTROLETYPE *comp_role;
1033             comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1034             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
1035                     comp_role->cRole);
1036 
1037             if ((m_state == OMX_StateLoaded)&&
1038                     !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1039             {
1040                 DEBUG_PRINT_LOW("Set Parameter called in valid state");
1041             }
1042             else
1043             {
1044                 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
1045                 RETURN(OMX_ErrorIncorrectStateOperation);
1046             }
1047 
1048             if (SWVENC_CODEC_MPEG4 == m_codec)
1049             {
1050                 if (!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
1051                 {
1052                     strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
1053                 }
1054                 else
1055                 {
1056                     DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
1057                     eRet = OMX_ErrorUnsupportedSetting;
1058                 }
1059             }
1060             else if (SWVENC_CODEC_H263 == m_codec)
1061             {
1062                 if (!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE))
1063                 {
1064                     strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
1065                 }
1066                 else
1067                 {
1068                     DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
1069                     eRet =OMX_ErrorUnsupportedSetting;
1070                 }
1071             }
1072             else
1073             {
1074                 DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", m_nkind);
1075                 eRet = OMX_ErrorInvalidComponentName;
1076             }
1077             break;
1078         }
1079 
1080         case OMX_IndexParamPriorityMgmt:
1081         {
1082             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt");
1083             if (m_state != OMX_StateLoaded) {
1084                 DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
1085                 RETURN(OMX_ErrorIncorrectStateOperation);
1086             }
1087             OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
1088             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
1089                     priorityMgmtype->nGroupID);
1090 
1091             DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
1092                     priorityMgmtype->nGroupPriority);
1093 
1094             m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID;
1095             m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority;
1096 
1097             break;
1098         }
1099 
1100         case OMX_IndexParamCompBufferSupplier:
1101         {
1102             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier");
1103             OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
1104             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
1105                     bufferSupplierType->eBufferSupplier);
1106             if ( (bufferSupplierType->nPortIndex == 0) ||
1107                  (bufferSupplierType->nPortIndex ==1)
1108                )
1109             {
1110                 m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
1111             }
1112             else
1113             {
1114                 eRet = OMX_ErrorBadPortIndex;
1115             }
1116 
1117             break;
1118 
1119         }
1120 
1121         case OMX_IndexParamVideoQuantization:
1122         {
1123             // this is applicable only for RC-off case
1124             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization");
1125             OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
1126             if (session_qp->nPortIndex == PORT_INDEX_OUT)
1127             {
1128                 Prop.id = SWVENC_PROPERTY_ID_QP;
1129                 Prop.info.qp.qp_i = session_qp->nQpI;
1130                 Prop.info.qp.qp_p = session_qp->nQpP;
1131                 Prop.info.qp.qp_b = session_qp->nQpB;
1132 
1133                 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1134                 if (Ret != SWVENC_S_SUCCESS)
1135                 {
1136                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1137                      __FUNCTION__, Ret);
1138                    RETURN(OMX_ErrorUnsupportedSetting);
1139                 }
1140 
1141                 m_sSessionQuantization.nQpI = session_qp->nQpI;
1142                 m_sSessionQuantization.nQpP = session_qp->nQpP;
1143                 m_sSessionQuantization.nQpB = session_qp->nQpB;
1144             }
1145             else
1146             {
1147                 DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
1148                 eRet = OMX_ErrorBadPortIndex;
1149             }
1150             break;
1151         }
1152 
1153         case OMX_QcomIndexParamVideoIPBQPRange:
1154         {
1155             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoIPBQPRange");
1156             OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *session_qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
1157             if (session_qp_range->nPortIndex == PORT_INDEX_OUT)
1158             {
1159                 Prop.id = SWVENC_PROPERTY_ID_QP_RANGE;
1160                 Prop.info.qp_range.min_qp_packed = ((session_qp_range->minBQP << 16) |
1161                                                     (session_qp_range->minPQP <<  8) |
1162                                                     (session_qp_range->minIQP <<  0));
1163                 Prop.info.qp_range.max_qp_packed = ((session_qp_range->maxBQP << 16) |
1164                                                     (session_qp_range->maxPQP <<  8) |
1165                                                     (session_qp_range->maxIQP <<  0));
1166 
1167                 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1168                 if (Ret != SWVENC_S_SUCCESS)
1169                 {
1170                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1171                      __FUNCTION__, Ret);
1172                    RETURN(OMX_ErrorUnsupportedSetting);
1173                 }
1174 
1175                 m_sSessionQPRange.minIQP = session_qp_range->minIQP;
1176                 m_sSessionQPRange.maxIQP = session_qp_range->maxIQP;
1177                 m_sSessionQPRange.minPQP = session_qp_range->minPQP;
1178                 m_sSessionQPRange.maxPQP = session_qp_range->maxPQP;
1179                 m_sSessionQPRange.minBQP = session_qp_range->minBQP;
1180                 m_sSessionQPRange.maxBQP = session_qp_range->maxBQP;
1181             }
1182             else
1183             {
1184                 DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP range setting");
1185                 eRet = OMX_ErrorBadPortIndex;
1186             }
1187             break;
1188         }
1189 
1190         case OMX_QcomIndexPortDefn:
1191         {
1192             OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam =
1193                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData;
1194             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn");
1195             if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN)
1196             {
1197                 if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1198                         pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1199                 {
1200                     m_use_input_pmem = OMX_TRUE;
1201                 }
1202                 else
1203                 {
1204                     m_use_input_pmem = OMX_FALSE;
1205                 }
1206             }
1207             else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1208             {
1209                 if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1210                         pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1211                 {
1212                     m_use_output_pmem = OMX_TRUE;
1213                 }
1214                 else
1215                 {
1216                     m_use_output_pmem = OMX_FALSE;
1217                 }
1218             }
1219             else
1220             {
1221                 DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn");
1222                 RETURN(OMX_ErrorBadPortIndex);
1223             }
1224             break;
1225         }
1226 
1227         case OMX_IndexParamVideoErrorCorrection:
1228         {
1229             DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
1230             OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
1231                 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1232 
1233             /* HEC */
1234             if (m_codec == SWVENC_CODEC_MPEG4)
1235             {
1236                Prop.id = SWVENC_PROPERTY_ID_MPEG4_HEC;
1237                Prop.info.mpeg4_hec = pParam->bEnableHEC;
1238 
1239                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1240                if (Ret != SWVENC_S_SUCCESS)
1241                {
1242                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1243                     __FUNCTION__, Ret);
1244                   RETURN(OMX_ErrorUndefined);
1245                }
1246 
1247                /* Data partitioning */
1248                Prop.id = SWVENC_PROPERTY_ID_MPEG4_DP;
1249                Prop.info.mpeg4_dp = pParam->bEnableDataPartitioning;
1250 
1251                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1252                if (Ret != SWVENC_S_SUCCESS)
1253                {
1254                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1255                     __FUNCTION__, Ret);
1256                   RETURN(OMX_ErrorUndefined);
1257                }
1258             }
1259 
1260             /* RVLC */
1261             if (pParam->bEnableRVLC)
1262             {
1263                DEBUG_PRINT_ERROR("%s, RVLC not support", __FUNCTION__);
1264             }
1265 
1266             /* Re-sync Marker */
1267             Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG;
1268             if ( (m_codec != SWVENC_CODEC_H263) && (pParam->bEnableDataPartitioning) )
1269             {
1270                DEBUG_PRINT_ERROR("DataPartioning are not Supported for this codec");
1271                break;
1272             }
1273             if ( (m_codec != SWVENC_CODEC_H263) && (pParam->nResynchMarkerSpacing) )
1274             {
1275                Prop.info.slice_config.mode = SWVENC_SLICE_MODE_BYTE;
1276                Prop.info.slice_config.size = ALIGN(pParam->nResynchMarkerSpacing, 8) >> 3; //slice size is defined in bits
1277                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1278                if (Ret != SWVENC_S_SUCCESS)
1279                {
1280                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1281                     __FUNCTION__, Ret);
1282                   RETURN(OMX_ErrorUndefined);
1283                }
1284             }
1285             else if ( (SWVENC_CODEC_H263 == m_codec) && (pParam->bEnableResync) )
1286             {
1287                Prop.info.slice_config.mode = SWVENC_SLICE_MODE_GOB;
1288                Prop.info.slice_config.size = 0;
1289                Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1290                if (Ret != SWVENC_S_SUCCESS)
1291                {
1292                   DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1293                     __FUNCTION__, Ret);
1294                   RETURN(OMX_ErrorUndefined);
1295                }
1296             }
1297             else
1298             {
1299                Prop.info.slice_config.mode = SWVENC_SLICE_MODE_OFF;
1300                Prop.info.slice_config.size = 0;
1301             }
1302 
1303             memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
1304             break;
1305         }
1306 
1307         case OMX_IndexParamVideoIntraRefresh:
1308         {
1309             DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
1310             OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
1311                 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1312 
1313             Ret = swvenc_set_intra_refresh(pParam);
1314             if (Ret != SWVENC_S_SUCCESS)
1315             {
1316                DEBUG_PRINT_ERROR("%s, swvenc_set_intra_refresh failed (%d)",
1317                  __FUNCTION__, Ret);
1318                RETURN(OMX_ErrorUnsupportedSetting);
1319             }
1320 
1321             memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
1322             break;
1323         }
1324 
1325         case OMX_QcomIndexParamVideoMetaBufferMode:
1326         {
1327             StoreMetaDataInBuffersParams *pParam =
1328                 (StoreMetaDataInBuffersParams*)paramData;
1329             DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
1330                     "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData);
1331 
1332             if (pParam->nPortIndex == PORT_INDEX_IN)
1333             {
1334                 if (pParam->bStoreMetaData != meta_mode_enable)
1335                 {
1336                     meta_mode_enable = pParam->bStoreMetaData;
1337                     if (!meta_mode_enable)
1338                     {
1339                         Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
1340                                  &m_sOutPortDef.nBufferCountActual,
1341                                  &m_sOutPortDef.nBufferSize,
1342                                  &m_sOutPortDef.nBufferAlignment,
1343                                  m_sOutPortDef.nPortIndex);
1344                         if (Ret != SWVENC_S_SUCCESS)
1345                         {
1346                            DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
1347                               Ret);
1348                            eRet = OMX_ErrorUndefined;
1349                            break;
1350                         }
1351                     }
1352                 }
1353             }
1354             else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session)
1355             {
1356                 if (pParam->bStoreMetaData != meta_mode_enable)
1357                 {
1358                     meta_mode_enable = pParam->bStoreMetaData;
1359                 }
1360             }
1361             else
1362             {
1363                 if (pParam->bStoreMetaData)
1364                 {
1365                     DEBUG_PRINT_ERROR("set_parameter: metamode is "
1366                             "valid for input port only");
1367                     eRet = OMX_ErrorUnsupportedIndex;
1368                 }
1369             }
1370         }
1371         break;
1372 
1373         case OMX_QcomIndexParamIndexExtraDataType:
1374         {
1375             DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
1376             QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1377             OMX_U32 mask = 0;
1378 
1379             if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
1380             {
1381                 if (pParam->nPortIndex == PORT_INDEX_OUT)
1382                 {
1383                     mask = VEN_EXTRADATA_SLICEINFO;
1384 
1385                     DEBUG_PRINT_HIGH("SliceInfo extradata %s",
1386                             ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1387                 }
1388                 else
1389                 {
1390                     DEBUG_PRINT_ERROR("set_parameter: Slice information is "
1391                             "valid for output port only");
1392                     eRet = OMX_ErrorUnsupportedIndex;
1393                     break;
1394                 }
1395             }
1396             else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo)
1397             {
1398                 if (pParam->nPortIndex == PORT_INDEX_OUT)
1399                 {
1400                     mask = VEN_EXTRADATA_MBINFO;
1401 
1402                     DEBUG_PRINT_HIGH("MBInfo extradata %s",
1403                             ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1404                 }
1405                 else
1406                 {
1407                     DEBUG_PRINT_ERROR("set_parameter: MB information is "
1408                             "valid for output port only");
1409                     eRet = OMX_ErrorUnsupportedIndex;
1410                     break;
1411                 }
1412             }
1413             else
1414             {
1415                 DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)",
1416                         pParam->nIndex);
1417                 eRet = OMX_ErrorUnsupportedIndex;
1418                 break;
1419             }
1420 
1421 
1422             if (pParam->bEnabled == OMX_TRUE)
1423             {
1424                 m_sExtraData |= mask;
1425             }
1426             else
1427             {
1428                 m_sExtraData &= ~mask;
1429             }
1430 
1431             #if 0
1432             // TBD: add setprop to swvenc once the support is added
1433             if (handle->venc_set_param((OMX_PTR)!!(m_sExtraData & mask),
1434                         (OMX_INDEXTYPE)pParam->nIndex) != true)
1435             {
1436                 DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex);
1437                 RETURN(OMX_ErrorUnsupportedSetting);
1438             }
1439             else
1440             #endif
1441             {
1442                 m_sOutPortDef.nPortIndex = PORT_INDEX_OUT;
1443                 bResult = dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
1444                         &m_sOutPortDef.nBufferCountActual,
1445                         &m_sOutPortDef.nBufferSize,
1446                         m_sOutPortDef.nPortIndex);
1447                 if (false == bResult)
1448                 {
1449                    DEBUG_PRINT_ERROR("dev_get_buf_req failed");
1450                    eRet = OMX_ErrorUndefined;
1451                    break;
1452                 }
1453 
1454                 DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%u, "
1455                         "count min=%u, buffer size=%u",
1456                         m_sOutPortDef.nBufferCountActual,
1457                         m_sOutPortDef.nBufferCountMin,
1458                         m_sOutPortDef.nBufferSize);
1459             }
1460             break;
1461         }
1462 
1463         case OMX_QcomIndexEnableH263PlusPType:
1464         {
1465             QOMX_EXTNINDEX_PARAMTYPE* pParam =
1466                 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1467             DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
1468             if (pParam->nPortIndex == PORT_INDEX_OUT)
1469             {
1470                 DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
1471                 RETURN(OMX_ErrorUnsupportedSetting);
1472             }
1473             else
1474             {
1475                 DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType "
1476                         "called on wrong port(%u)", pParam->nPortIndex);
1477                 RETURN(OMX_ErrorBadPortIndex);
1478             }
1479             break;
1480         }
1481 
1482         case QOMX_IndexParamVideoInitialQp:
1483         {
1484             // TBD: applicable to RC-on case only
1485             DEBUG_PRINT_ERROR("ERROR: Setting Initial QP for RC-on case");
1486             RETURN(OMX_ErrorNone);
1487             break;
1488         }
1489 
1490         case OMX_QTIIndexParamEnableAVTimerTimestamps:
1491         {
1492             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
1493             QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1494             m_bUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
1495             DEBUG_PRINT_INFO("AVTimer timestamps %s", m_bUseAVTimerTimestamps ? "enabled" : "disabled");
1496             break;
1497         }
1498 
1499         default:
1500         {
1501             DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex);
1502             eRet = OMX_ErrorUnsupportedIndex;
1503             break;
1504         }
1505     }
1506 
1507     RETURN(eRet);
1508 }
1509 
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)1510 OMX_ERRORTYPE  omx_venc::set_config
1511 (
1512    OMX_IN OMX_HANDLETYPE      hComp,
1513    OMX_IN OMX_INDEXTYPE configIndex,
1514    OMX_IN OMX_PTR        configData
1515 )
1516 {
1517     ENTER_FUNC();
1518 
1519     SWVENC_STATUS SwStatus;
1520 
1521     (void)hComp;
1522 
1523     if (configData == NULL)
1524     {
1525         DEBUG_PRINT_ERROR("ERROR: param is null");
1526         RETURN(OMX_ErrorBadParameter);
1527     }
1528 
1529     if (m_state == OMX_StateInvalid)
1530     {
1531         DEBUG_PRINT_ERROR("ERROR: config called in Invalid state");
1532         RETURN(OMX_ErrorIncorrectStateOperation);
1533     }
1534 
1535     switch ((int)configIndex)
1536     {
1537         case OMX_IndexConfigVideoBitrate:
1538         {
1539             OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
1540                 reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
1541             DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate);
1542 
1543             if (pParam->nPortIndex == PORT_INDEX_OUT)
1544             {
1545                 SwStatus = swvenc_set_bit_rate(pParam->nEncodeBitrate);
1546                 if (SwStatus != SWVENC_S_SUCCESS)
1547                 {
1548                    DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
1549                      __FUNCTION__, SwStatus);
1550                    RETURN(OMX_ErrorUnsupportedSetting);
1551                 }
1552 
1553                 m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
1554                 m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
1555                 m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
1556             }
1557             else
1558             {
1559                 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1560                 RETURN(OMX_ErrorBadPortIndex);
1561             }
1562             break;
1563         }
1564         case OMX_IndexConfigVideoFramerate:
1565         {
1566             OMX_CONFIG_FRAMERATETYPE* pParam =
1567                 reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
1568             DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate);
1569 
1570             if (pParam->nPortIndex == PORT_INDEX_OUT)
1571             {
1572                 SwStatus = swvenc_set_frame_rate(pParam->xEncodeFramerate >> 16);
1573                 if (SwStatus != SWVENC_S_SUCCESS)
1574                 {
1575                    DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
1576                      __FUNCTION__, SwStatus);
1577                    RETURN(OMX_ErrorUnsupportedSetting);
1578                 }
1579 
1580                 m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
1581                 m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
1582                 m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
1583             }
1584             else
1585             {
1586                 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1587                 RETURN(OMX_ErrorBadPortIndex);
1588             }
1589             break;
1590         }
1591         case QOMX_IndexConfigVideoIntraperiod:
1592         {
1593             QOMX_VIDEO_INTRAPERIODTYPE* pParam =
1594                 reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
1595             DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod");
1596 
1597             if (pParam->nPortIndex == PORT_INDEX_OUT)
1598             {
1599                 if (pParam->nBFrames > 0)
1600                 {
1601                     DEBUG_PRINT_ERROR("B frames not supported");
1602                     RETURN(OMX_ErrorUnsupportedSetting);
1603                 }
1604 
1605                 DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
1606                         m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames,
1607                         pParam->nPFrames, pParam->nBFrames);
1608                 if (m_sIntraperiod.nBFrames != pParam->nBFrames)
1609                 {
1610                     DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported");
1611                     RETURN(OMX_ErrorUnsupportedSetting);
1612                 }
1613 
1614                 /* set the intra period */
1615                 SwStatus = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
1616                 if (SwStatus != SWVENC_S_SUCCESS)
1617                 {
1618                    DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
1619                      __FUNCTION__, SwStatus);
1620                    RETURN(OMX_ErrorUnsupportedSetting);
1621                 }
1622 
1623                 m_sIntraperiod.nPFrames = pParam->nPFrames;
1624                 m_sIntraperiod.nBFrames = pParam->nBFrames;
1625                 m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod;
1626 
1627                 if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
1628                 {
1629                     m_sParamMPEG4.nPFrames = pParam->nPFrames;
1630                     if (m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple)
1631                     {
1632                         m_sParamMPEG4.nBFrames = pParam->nBFrames;
1633                     }
1634                     else
1635                     {
1636                         m_sParamMPEG4.nBFrames = 0;
1637                     }
1638                 }
1639                 else if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263)
1640                 {
1641                     m_sParamH263.nPFrames = pParam->nPFrames;
1642                 }
1643             }
1644             else
1645             {
1646                 DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
1647                 RETURN(OMX_ErrorBadPortIndex);
1648             }
1649 
1650             break;
1651         }
1652         case OMX_IndexConfigVideoIntraVOPRefresh:
1653         {
1654             OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
1655                 reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
1656             DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh");
1657 
1658             if (pParam->nPortIndex == PORT_INDEX_OUT)
1659             {
1660 
1661                 SWVENC_PROPERTY Prop;
1662 
1663                 Prop.id = SWVENC_PROPERTY_ID_IFRAME_REQUEST;
1664 
1665                 SwStatus = swvenc_setproperty(m_hSwVenc, &Prop);
1666                 if (SwStatus != SWVENC_S_SUCCESS)
1667                 {
1668                    DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1669                      __FUNCTION__, SwStatus);
1670                    RETURN(OMX_ErrorUnsupportedSetting);
1671                 }
1672 
1673                 m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
1674             }
1675             else
1676             {
1677                 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1678                 RETURN(OMX_ErrorBadPortIndex);
1679             }
1680             break;
1681         }
1682         case OMX_IndexConfigCommonRotate:
1683         {
1684             if (m_codec == SWVENC_CODEC_H263) {
1685                 OMX_CONFIG_ROTATIONTYPE *pParam =
1686                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE *>(configData);
1687                 DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigCommonRotate");
1688                 m_bIsRotationSupported = true;
1689 
1690                 // XXX: diffrent from h/w encoder rotation, h/w encoder only need to update out
1691                 // port info. For h/w encoder, rotation is processed in h/w encoder firmware, this
1692                 // is after ETB, so input info doesn't change. While s/w encoder rotation is
1693                 // processed before ETB, so need to change in port info.
1694                 if (pParam->nPortIndex != PORT_INDEX_IN) {
1695                     DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u",
1696                             (unsigned int)pParam->nPortIndex);
1697                     RETURN(OMX_ErrorBadPortIndex);
1698                 }
1699                 if (pParam->nRotation == 0 ||
1700                         pParam->nRotation == 90 ||
1701                         pParam->nRotation == 180 ||
1702                         pParam->nRotation == 270) {
1703                     DEBUG_PRINT_HIGH("set_config(): Rotation Angle %u",
1704                             (unsigned int)pParam->nRotation);
1705                     if (m_pIpbuffers == nullptr) {
1706                         // m_pIpbuffers is used to store original ipbuffer, because after rotation,
1707                         // will send new rotated ipbuffer to encoder, in EBD will also get new
1708                         // ipbuffer. so we can restore original ipbuffer from to m_pIpbuffers and
1709                         // return it to framework
1710                         m_pIpbuffers = new SWVENC_IPBUFFER[m_sInPortDef.nBufferCountActual];
1711                     }
1712                     if (m_pIpbuffers == nullptr) {
1713                         DEBUG_PRINT_ERROR("create ipbuffer array failed");
1714                         return OMX_ErrorUndefined;
1715                     }
1716                 } else {
1717                     DEBUG_PRINT_ERROR("ERROR: Unsupported Rotation Angle %u",
1718                             (unsigned int)pParam->nRotation);
1719                     RETURN(OMX_ErrorUnsupportedSetting);
1720                 }
1721                 if (m_sConfigFrameRotation.nRotation == pParam->nRotation) {
1722                     DEBUG_PRINT_HIGH("set_config(): rotation (%d) not changed", pParam->nRotation);
1723                     break;
1724                 }
1725 
1726                 OMX_S32 rotation_diff = pParam->nRotation - m_sConfigFrameRotation.nRotation;
1727                 if (rotation_diff < 0)
1728                     rotation_diff = -rotation_diff;
1729                 if (rotation_diff == 90 || rotation_diff == 270) {
1730                     // in the case that rotation angle is 90 or 270 degree, if original buffer size
1731                     // is 640x480, after rotation, rotated buffer size will be 480x640, so need to
1732                     // flip dimensions in such cases.
1733                     m_bDimensionsNeedFlip = true;
1734                     OMX_ERRORTYPE err = OMX_ErrorNone;
1735                     // flip and set new dimensions must be called after real dimension set
1736                     if (m_bIsInFrameSizeSet && !m_bIsInFlipDone) {
1737                         err = swvenc_do_flip_inport();
1738                         if (err != OMX_ErrorNone) {
1739                             DEBUG_PRINT_ERROR("set_config(): flipping failed");
1740                             RETURN(err);
1741                         }
1742 
1743                         m_bIsInFlipDone = true;
1744                     } else {
1745                         DEBUG_PRINT_HIGH("set_config(): in port frame size isn't set, will do flip later");
1746                     }
1747                     if (m_bIsOutFrameSizeSet && !m_bIsOutFlipDone) {
1748                         err = swvenc_do_flip_outport();
1749                         m_bIsOutFlipDone = true;
1750                         DEBUG_PRINT_HIGH("set_config(): out port flip done, rotation (%d), flipped WxH (%d x %d)",
1751                                 pParam->nRotation,
1752                                 m_sOutPortDef.format.video.nFrameWidth,
1753                                 m_sOutPortDef.format.video.nFrameHeight);
1754                     } else {
1755                         DEBUG_PRINT_HIGH("set_config(): out port frame size isn't set, will do flip later");
1756                     }
1757                 } else {
1758                     m_bDimensionsNeedFlip = false;
1759                     DEBUG_PRINT_HIGH("set_config(): rotation (%d), no need to flip WxH",
1760                             pParam->nRotation);
1761                 }
1762 
1763                 // save rotation angle
1764                 m_sConfigFrameRotation.nRotation = pParam->nRotation;
1765                 break;
1766             } else {
1767                 DEBUG_PRINT_ERROR("ERROR: rotation is not supported for current codec");
1768                 RETURN(OMX_ErrorUnsupportedSetting);
1769 
1770 
1771             }
1772         }
1773         case OMX_IndexConfigAndroidVendorExtension:
1774         {
1775             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
1776                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
1777             OMX_ERRORTYPE err = set_vendor_extension_config(ext);
1778             RETURN(err);
1779         }
1780         default:
1781             DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
1782             RETURN(OMX_ErrorUnsupportedSetting);
1783             break;
1784     }
1785 
1786     EXIT_FUNC();
1787 
1788     RETURN(OMX_ErrorNone);
1789 }
1790 
swvenc_do_flip_inport()1791 OMX_ERRORTYPE omx_venc::swvenc_do_flip_inport() {
1792     ENTER_FUNC();
1793     OMX_U32 inWidth = m_sInPortDef.format.video.nFrameWidth;
1794     OMX_U32 inHeight = m_sInPortDef.format.video.nFrameHeight;
1795 
1796     // set new dimensions to encoder
1797     SWVENC_PROPERTY Prop;
1798     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
1799     Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
1800     Prop.info.frame_size.height = inWidth;
1801     Prop.info.frame_size.width = inHeight;
1802 
1803     DEBUG_PRINT_HIGH("setting flipped dimensions to swencoder, WxH (%d x %d)",
1804             Prop.info.frame_size.width, Prop.info.frame_size.height);
1805     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1806     if (Ret != SWVENC_S_SUCCESS) {
1807         // currently, set dimensions to encoder can only be called when encoder is
1808         // in init state, while setVendorParameter() in ACodec can be called when
1809         // OMX component is in Executing state, in this case, encoder is in ready
1810         // state, will report unsupported error.
1811         DEBUG_PRINT_ERROR("ERROR: setting new dimension to encoder failed (%d)",
1812                 Ret);
1813         return OMX_ErrorUnsupportedSetting;
1814     }
1815 
1816     // don't flip in port dimensions m_sInPortDef.format.video.nFrameWidth(mFrameHeight)
1817     // app may require this dimensions by get_parameter
1818 
1819     // update attributes, here dimensions are flipped, so use inHeight for calculating
1820     // stride, inWidth for scanlines, and swapp parameters in venus size calculation
1821     int stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12, inHeight);
1822     int scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12, inWidth);
1823     Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
1824     Prop.info.frame_attributes.stride_luma = stride;
1825     Prop.info.frame_attributes.stride_chroma = stride;
1826     Prop.info.frame_attributes.offset_luma = 0;
1827     Prop.info.frame_attributes.offset_chroma = scanlines * stride;
1828     Prop.info.frame_attributes.size =
1829         SWVENC_BUFFER_SIZE(COLOR_FMT_NV12_ZSL, inHeight, inWidth);
1830 
1831     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1832     if (Ret != SWVENC_S_SUCCESS) {
1833         DEBUG_PRINT_ERROR("ERROR: update frame attributes failed (%d)", Ret);
1834         return OMX_ErrorUnsupportedSetting;
1835     }
1836 
1837     // till now, attributes of omx input port is different from sw encoder input port,
1838     // omx input port stores original attributes, sw encoder input port stores flipped
1839     // attributes. no need to update buffer requirements from sw encoder here, but need
1840     // to update in output port, omx output port should also store flipped attrinutes
1841 
1842     EXIT_FUNC();
1843     return OMX_ErrorNone;
1844 }
1845 
swvenc_do_flip_outport()1846 OMX_ERRORTYPE omx_venc::swvenc_do_flip_outport() {
1847     ENTER_FUNC();
1848     // for out port, no need to set dimensions to encoder
1849     OMX_U32 outWidth = m_sOutPortDef.format.video.nFrameWidth;
1850     OMX_U32 outHeight = m_sOutPortDef.format.video.nFrameHeight;
1851 
1852     // update out port info
1853     m_sOutPortDef.format.video.nFrameWidth = outHeight;
1854     m_sOutPortDef.format.video.nFrameHeight = outWidth;
1855 
1856     // attributes in sw encoder has been updated after flipping dimensions, so need to update
1857     // omx out port buffer requirements, they should have the same attributes
1858     DEBUG_PRINT_LOW("flip outport, o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
1859     DEBUG_PRINT_LOW("flip outport, o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
1860     DEBUG_PRINT_LOW("flip outport, o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
1861 
1862     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
1863     Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
1864             &m_sOutPortDef.nBufferCountActual,
1865             &m_sOutPortDef.nBufferSize,
1866             &m_sOutPortDef.nBufferAlignment,
1867             PORT_INDEX_OUT);
1868     if (Ret != SWVENC_S_SUCCESS) {
1869         DEBUG_PRINT_ERROR("ERROR: %s, flip outport swvenc_get_buffer_req failed(%d)", __FUNCTION__,
1870                 Ret);
1871         return OMX_ErrorUndefined;
1872     }
1873 
1874     DEBUG_PRINT_LOW("flip outport, o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
1875     DEBUG_PRINT_LOW("flip outport, o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
1876     DEBUG_PRINT_LOW("flip outport, o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
1877 
1878     EXIT_FUNC();
1879     return OMX_ErrorNone;
1880 }
1881 
swvenc_do_rotate(int fd,SWVENC_IPBUFFER & ipbuffer,OMX_U32 index)1882 bool omx_venc::swvenc_do_rotate(int fd, SWVENC_IPBUFFER & ipbuffer, OMX_U32 index) {
1883     // declarations and definitions of variables rotation needs
1884     private_handle_t *privateHandle = nullptr;
1885 
1886     int s_width = m_sInPortDef.format.video.nFrameWidth;
1887     int s_height = m_sInPortDef.format.video.nFrameHeight;
1888     int d_width = m_bDimensionsNeedFlip ? s_height : s_width;
1889     int d_height = m_bDimensionsNeedFlip ? s_width : s_height;
1890 
1891     uint32_t rotation = m_sConfigFrameRotation.nRotation;
1892 
1893     uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN |
1894         GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_RENDER;
1895     uint32_t dstusage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
1896         GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_SW_READ_OFTEN |
1897         GraphicBuffer::USAGE_SW_WRITE_OFTEN;
1898 
1899     int src_stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12, s_width);
1900     int src_scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12, s_height);
1901     int src_size = SWVENC_BUFFER_SIZE(COLOR_FMT_NV12_ZSL, s_width, s_height);
1902     int dst_size = SWVENC_BUFFER_SIZE(COLOR_FMT_NV12_ZSL, d_width, d_height);
1903 
1904     uint32_t format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
1905 
1906     // privateHandle is created for creating GraphicBuffer in rotation case
1907     privateHandle = new private_handle_t(fd, ipbuffer.size, usage, BUFFER_TYPE_VIDEO, format,
1908             src_stride, src_scanlines);
1909     if (privateHandle == nullptr) {
1910         DEBUG_PRINT_ERROR("failed to create private handle");
1911         return false;
1912     }
1913 
1914     sp<GraphicBuffer> srcBuffer = new GraphicBuffer(s_width, s_height, format, 1, usage,
1915             src_stride, (native_handle_t *)privateHandle, false);
1916     if (srcBuffer.get() == NULL) {
1917         DEBUG_PRINT_ERROR("create source buffer failed");
1918         swvenc_delete_pointer(privateHandle);
1919         return false;
1920     }
1921 
1922     // reuse dstBuffer
1923     if (dstBuffer.get() == NULL) {
1924         dstBuffer = new GraphicBuffer(d_width, d_height, format, dstusage);
1925     }
1926     if (dstBuffer.get() == NULL) {
1927         DEBUG_PRINT_ERROR("create destination buffer failed");
1928         swvenc_delete_pointer(privateHandle);
1929         return false;
1930     }
1931     SWVENC_STATUS ret = swvenc_rotateFrame(s_width, s_height, d_height, d_width,
1932             rotation, srcBuffer->getNativeBuffer(), dstBuffer->getNativeBuffer());
1933 
1934     if (ret == SWVENC_S_SUCCESS) {
1935         void *buf = nullptr;
1936         if (dstBuffer->lock(dstusage, &buf) == 0 && buf != nullptr) {
1937             DEBUG_PRINT_HIGH("store original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)], new ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]",
1938                     ipbuffer.p_buffer,
1939                     ipbuffer.size,
1940                     ipbuffer.filled_length,
1941                     (unsigned char *)buf,
1942                     dst_size,
1943                     dst_size);
1944             if (index >= m_sInPortDef.nBufferCountActual) {
1945                 DEBUG_PRINT_ERROR("incorrect buffer index");
1946                 swvenc_delete_pointer(privateHandle);
1947                 return false;
1948             }
1949             m_pIpbuffers[index].size = ipbuffer.size;
1950             m_pIpbuffers[index].filled_length = ipbuffer.filled_length;
1951             m_pIpbuffers[index].p_buffer = ipbuffer.p_buffer;
1952             ipbuffer.size = dst_size;
1953             ipbuffer.filled_length = dst_size;
1954             ipbuffer.p_buffer = (unsigned char *)buf;
1955             dstBuffer->unlock();
1956             DEBUG_PRINT_HIGH("copy rotated buffer successfully");
1957         } else {
1958             DEBUG_PRINT_ERROR("copy rotated buffer failed");
1959             swvenc_delete_pointer(privateHandle);
1960             return false;
1961         }
1962     } else {
1963         DEBUG_PRINT_ERROR("rotate failed");
1964         swvenc_delete_pointer(privateHandle);
1965         return false;
1966     }
1967 
1968     swvenc_delete_pointer(privateHandle);
1969     return true;
1970 }
1971 
component_deinit(OMX_IN OMX_HANDLETYPE hComp)1972 OMX_ERRORTYPE  omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
1973 {
1974     ENTER_FUNC();
1975 
1976     OMX_U32 i = 0;
1977     DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()");
1978 
1979     (void)hComp;
1980 
1981     if (m_bIsRotationSupported) {
1982         swvenc_rotation_deinit();
1983         if (m_pIpbuffers != nullptr) {
1984             delete [] m_pIpbuffers;
1985         }
1986     }
1987 
1988     if (OMX_StateLoaded != m_state)
1989     {
1990         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",
1991                 m_state);
1992     }
1993     if (m_out_mem_ptr)
1994     {
1995         DEBUG_PRINT_LOW("Freeing the Output Memory");
1996         for (i=0; i< m_sOutPortDef.nBufferCountActual; i++ )
1997         {
1998             free_output_buffer (&m_out_mem_ptr[i]);
1999         }
2000         free(m_out_mem_ptr);
2001         m_out_mem_ptr = NULL;
2002     }
2003 
2004     /* Check if the input buffers have to be cleaned up */
2005     if ( m_inp_mem_ptr && !meta_mode_enable )
2006     {
2007         DEBUG_PRINT_LOW("Freeing the Input Memory");
2008         for (i=0; i<m_sInPortDef.nBufferCountActual; i++)
2009         {
2010             free_input_buffer (&m_inp_mem_ptr[i]);
2011         }
2012 
2013         free(m_inp_mem_ptr);
2014         m_inp_mem_ptr = NULL;
2015     }
2016 
2017     /* Reset counters in msg queues */
2018     m_ftb_q.m_size=0;
2019     m_cmd_q.m_size=0;
2020     m_etb_q.m_size=0;
2021     m_ftb_q.m_read = m_ftb_q.m_write =0;
2022     m_cmd_q.m_read = m_cmd_q.m_write =0;
2023     m_etb_q.m_read = m_etb_q.m_write =0;
2024 
2025     DEBUG_PRINT_HIGH("Calling swvenc_deinit()");
2026     swvenc_deinit(m_hSwVenc);
2027 
2028     if (msg_thread_created) {
2029         msg_thread_created = false;
2030         msg_thread_stop = true;
2031         post_message(this, OMX_COMPONENT_CLOSE_MSG);
2032         DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
2033         pthread_join(msg_thread_id,NULL);
2034     }
2035     DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit");
2036 
2037     RETURN(OMX_ErrorNone);
2038 }
2039 
dev_stop(void)2040 OMX_U32 omx_venc::dev_stop(void)
2041 {
2042     ENTER_FUNC();
2043 
2044     SWVENC_STATUS Ret;
2045 
2046     if (false == m_stopped)
2047     {
2048        Ret = swvenc_stop(m_hSwVenc);
2049        if (Ret != SWVENC_S_SUCCESS)
2050        {
2051           DEBUG_PRINT_ERROR("%s, swvenc_stop failed (%d)",
2052             __FUNCTION__, Ret);
2053           RETURN(-1);
2054        }
2055        set_format = false;
2056        m_stopped = true;
2057 
2058        /* post STOP_DONE event as start is synchronus */
2059        post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_STOP_DONE);
2060     }
2061 
2062     RETURN(0);
2063 }
2064 
dev_pause(void)2065 OMX_U32 omx_venc::dev_pause(void)
2066 {
2067     ENTER_FUNC();
2068     // nothing to be done for sw encoder
2069 
2070     RETURN(true);
2071 }
2072 
dev_resume(void)2073 OMX_U32 omx_venc::dev_resume(void)
2074 {
2075     ENTER_FUNC();
2076     // nothing to be done for sw encoder
2077 
2078     RETURN(true);
2079 }
2080 
dev_start(void)2081 OMX_U32 omx_venc::dev_start(void)
2082 {
2083    ENTER_FUNC();
2084    SWVENC_STATUS Ret;
2085    Ret = swvenc_start(m_hSwVenc);
2086    if (Ret != SWVENC_S_SUCCESS)
2087    {
2088       DEBUG_PRINT_ERROR("%s, swvenc_start failed (%d)",
2089         __FUNCTION__, Ret);
2090       RETURN(-1);
2091    }
2092 
2093    m_stopped = false;
2094    if (m_bIsRotationSupported){
2095        Ret = swvenc_rotation_init();
2096        if (Ret == SWVENC_S_UNSUPPORTED) {
2097            DEBUG_PRINT_ERROR("ERROR: Rotation not supported for this target");
2098            m_bIsRotationSupported = false;
2099         }
2100    }
2101    RETURN(0);
2102 }
2103 
dev_flush(unsigned port)2104 OMX_U32 omx_venc::dev_flush(unsigned port)
2105 {
2106    ENTER_FUNC();
2107    SWVENC_STATUS Ret;
2108 
2109    (void)port;
2110    Ret = swvenc_flush(m_hSwVenc);
2111    if (Ret != SWVENC_S_SUCCESS)
2112    {
2113       DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
2114         __FUNCTION__, Ret);
2115       RETURN(-1);
2116    }
2117 
2118    RETURN(0);
2119 }
2120 
dev_start_done(void)2121 OMX_U32 omx_venc::dev_start_done(void)
2122 {
2123    ENTER_FUNC();
2124 
2125    /* post START_DONE event as start is synchronus */
2126    post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_START_DONE);
2127 
2128    RETURN(0);
2129 }
2130 
dev_set_message_thread_id(pthread_t tid)2131 OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid)
2132 {
2133     ENTER_FUNC();
2134 
2135     // nothing to be done for sw encoder
2136     (void)tid;
2137 
2138     RETURN(true);
2139 }
2140 
dev_use_buf(unsigned port)2141 bool omx_venc::dev_use_buf(unsigned port)
2142 {
2143     ENTER_FUNC();
2144     (void)port;
2145     RETURN(true);
2146 }
2147 
dev_handle_empty_eos_buffer(void)2148 bool omx_venc::dev_handle_empty_eos_buffer(void)
2149 {
2150     ENTER_FUNC();
2151     SWVENC_STATUS Ret;
2152     SWVENC_IPBUFFER ipbuffer;
2153     ipbuffer.p_buffer = NULL;
2154     ipbuffer.filled_length =0;
2155     ipbuffer.flags = SWVENC_FLAG_EOS;
2156     Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
2157     if (Ret != SWVENC_S_SUCCESS)
2158     {
2159        DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
2160          __FUNCTION__, Ret);
2161        RETURN(false);
2162     }
2163     RETURN(true);
2164 }
2165 
dev_free_buf(void * buf_addr,unsigned port)2166 bool omx_venc::dev_free_buf(void *buf_addr,unsigned port)
2167 {
2168     ENTER_FUNC();
2169 
2170     (void)buf_addr;
2171     (void)port;
2172 
2173     RETURN(true);
2174 }
2175 
dev_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2176 bool omx_venc::dev_empty_buf
2177 (
2178     void *buffer,
2179     void *pmem_data_buf,
2180     unsigned index,
2181     unsigned fd
2182 )
2183 {
2184     ENTER_FUNC();
2185 
2186     SWVENC_STATUS Ret;
2187     SWVENC_IPBUFFER ipbuffer;
2188     OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2189     unsigned int size = 0, filled_length, offset = 0;
2190     SWVENC_COLOR_FORMAT color_format;
2191     SWVENC_PROPERTY prop;
2192 
2193     (void)pmem_data_buf;
2194     (void)index;
2195 
2196     if (meta_mode_enable)
2197     {
2198         LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
2199         meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
2200         if(m_sInPortDef.format.video.eColorFormat == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
2201         {
2202             DEBUG_PRINT_LOW("dev_empty_buf: color_format is QOMX_COLOR_FormatAndroidOpaque");
2203             set_format = true;
2204         }
2205         if(!meta_buf)
2206         {
2207             if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS))
2208             {
2209                 ipbuffer.p_buffer= bufhdr->pBuffer;
2210                 ipbuffer.size = bufhdr->nAllocLen;
2211                 ipbuffer.filled_length = bufhdr->nFilledLen;
2212                 DEBUG_PRINT_LOW("dev_empty_buf: empty EOS buffer");
2213             }
2214             else
2215             {
2216                 return false;
2217             }
2218         }
2219         else
2220         {
2221             if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
2222             {
2223                 offset = meta_buf->meta_handle->data[1];
2224                 size = meta_buf->meta_handle->data[2];
2225                 if (set_format && (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 5))
2226                 {
2227                     m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)meta_buf->meta_handle->data[5];
2228                 }
2229                 ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
2230                 if (ipbuffer.p_buffer == MAP_FAILED)
2231                 {
2232                     DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
2233                     RETURN(false);
2234                 }
2235                 ipbuffer.size = size;
2236                 ipbuffer.filled_length = size;
2237             }
2238             else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
2239             {
2240                 VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
2241                 private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
2242                 size = handle->size;
2243                 if (m_bUseAVTimerTimestamps) {
2244                     uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
2245                     if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
2246                             && avTimerTimestampNs > 0) {
2247                         bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
2248                         DEBUG_PRINT_LOW("AVTimer TS: %llu us", (unsigned long long)bufhdr->nTimeStamp);
2249                     }
2250                 }
2251                 if (set_format)
2252                 {
2253                     DEBUG_PRINT_LOW("color format = 0x%x",handle->format);
2254                     if (((OMX_COLOR_FORMATTYPE)handle->format) != m_sInPortFormat.eColorFormat)
2255                     {
2256                         if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
2257                         {
2258                             DEBUG_PRINT_LOW("HAL_PIXEL_FORMAT_NV12_ENCODEABLE ");
2259                             m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
2260                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2261                         }
2262                         else if(handle->format == HAL_PIXEL_FORMAT_NV21_ZSL)
2263                         {
2264                             /* HAL_PIXEL_FORMAT_NV21_ZSL format is NV21 format with 64,64 alignment,
2265                                this format support is added to address a CTS issue and OEM test app issue
2266                                which is trigerring this input format*/
2267                             DEBUG_PRINT_LOW("HAL_PIXEL_FORMAT_NV21_ZSL ");
2268                             m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
2269                                 HAL_PIXEL_FORMAT_NV21_ZSL;
2270                         }
2271                         else if (handle->format == QOMX_COLOR_FormatYVU420SemiPlanar)
2272                         {
2273                             DEBUG_PRINT_LOW("HAL_PIXEL_FORMAT_NV21_ENCODEABLE ");
2274                             m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
2275                                 QOMX_COLOR_FormatYVU420SemiPlanar;
2276                         }
2277                         else
2278                         {
2279                             DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat 0x%x invalid",
2280                                               __FUNCTION__,handle->format);
2281                             RETURN(false);
2282                         }
2283                     }
2284                 }
2285                 ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
2286                 if (ipbuffer.p_buffer == MAP_FAILED)
2287                 {
2288                     DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
2289                     RETURN(false);
2290                 }
2291                 ipbuffer.size = size;
2292                 ipbuffer.filled_length = size;
2293             }
2294             else
2295             {
2296                 //handles the use case for surface encode
2297                 ipbuffer.p_buffer = bufhdr->pBuffer;
2298                 ipbuffer.size = bufhdr->nAllocLen;
2299                 ipbuffer.filled_length = bufhdr->nFilledLen;
2300             }
2301             if (set_format)
2302             {
2303                 set_format = false;
2304                 m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
2305             }
2306         }
2307     }
2308     else
2309     {
2310         ipbuffer.p_buffer = bufhdr->pBuffer;
2311         ipbuffer.size = bufhdr->nAllocLen;
2312         ipbuffer.filled_length = bufhdr->nFilledLen;
2313     }
2314     if(update_offset)
2315     {
2316         update_offset = false;
2317         Ret = swvenc_set_color_format(m_sInPortFormat.eColorFormat);
2318         if (Ret != SWVENC_S_SUCCESS)
2319         {
2320             DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2321                              __FUNCTION__, Ret);
2322             RETURN(false);
2323         }
2324     }
2325     ipbuffer.flags = 0;
2326     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2327     {
2328       ipbuffer.flags |= SWVENC_FLAG_EOS;
2329     }
2330     ipbuffer.timestamp = bufhdr->nTimeStamp;
2331     ipbuffer.p_client_data = (unsigned char *)bufhdr;
2332 
2333     DEBUG_PRINT_LOW("ETB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
2334       ipbuffer.p_buffer,
2335       ipbuffer.size,
2336       ipbuffer.filled_length,
2337       (unsigned int)ipbuffer.flags,
2338       ipbuffer.timestamp,
2339       ipbuffer.p_client_data);
2340 
2341     if (m_debug.in_buffer_log)
2342     {
2343        // dump before rotation, un-rotated buffer
2344        swvenc_input_log_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length);
2345     }
2346 
2347     if (m_bIsRotationSupported && m_sConfigFrameRotation.nRotation != 0) {
2348         if(!swvenc_do_rotate((int)fd, ipbuffer, (OMX_U32)index)) {
2349             DEBUG_PRINT_ERROR("rotate failed");
2350             return OMX_ErrorUndefined;
2351         }
2352         if (m_debug.in_buffer_rotated_log) {
2353             // dump after rotation, rotated buffer
2354             DEBUG_PRINT_ERROR("dump rotated");
2355             swvenc_input_log_rotated_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length);
2356         }
2357     }
2358 
2359     Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
2360     if (Ret != SWVENC_S_SUCCESS)
2361     {
2362        DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
2363          __FUNCTION__, Ret);
2364        RETURN(false);
2365     }
2366 
2367     RETURN(true);
2368 }
2369 
dev_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2370 bool omx_venc::dev_fill_buf
2371 (
2372     void *buffer,
2373     void *pmem_data_buf,
2374     unsigned index,
2375     unsigned fd
2376 )
2377 {
2378     ENTER_FUNC();
2379 
2380     SWVENC_STATUS Ret;
2381 
2382     SWVENC_OPBUFFER opbuffer;
2383     OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2384 
2385     (void)pmem_data_buf;
2386     (void)index;
2387     (void)fd;
2388 
2389     opbuffer.p_buffer = bufhdr->pBuffer;
2390     opbuffer.size = bufhdr->nAllocLen;
2391     opbuffer.filled_length = bufhdr->nFilledLen;
2392     opbuffer.flags = bufhdr->nFlags;
2393     opbuffer.timestamp = bufhdr->nTimeStamp;
2394     opbuffer.p_client_data = (unsigned char *)bufhdr;
2395     opbuffer.frame_type = SWVENC_FRAME_TYPE_I;
2396 
2397     DEBUG_PRINT_LOW("FTB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
2398       opbuffer.p_buffer,
2399       opbuffer.size,
2400       opbuffer.filled_length,
2401       opbuffer.flags,
2402       opbuffer.timestamp,
2403       opbuffer.p_client_data);
2404 
2405     if ( false == m_bSeqHdrRequested)
2406     {
2407       if (dev_get_seq_hdr(opbuffer.p_buffer, opbuffer.size, &opbuffer.filled_length))
2408       {
2409          bufhdr->nFilledLen = opbuffer.filled_length;
2410          bufhdr->nOffset = 0;
2411          bufhdr->nTimeStamp = 0;
2412          bufhdr->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
2413 
2414          DEBUG_PRINT_LOW("sending FBD with codec config");
2415          m_bSeqHdrRequested = true;
2416          post_event ((unsigned long)bufhdr,0,OMX_COMPONENT_GENERATE_FBD);
2417       }
2418       else
2419       {
2420          DEBUG_PRINT_ERROR("ERROR: couldn't get sequence header");
2421          post_event(OMX_EventError,OMX_ErrorUndefined,OMX_COMPONENT_GENERATE_EVENT);
2422       }
2423     }
2424     else
2425     {
2426        Ret = swvenc_fillthisbuffer(m_hSwVenc, &opbuffer);
2427        if (Ret != SWVENC_S_SUCCESS)
2428        {
2429           DEBUG_PRINT_ERROR("%s, swvenc_fillthisbuffer failed (%d)",
2430             __FUNCTION__, Ret);
2431           RETURN(false);
2432        }
2433     }
2434 
2435     RETURN(true);
2436 }
2437 
dev_get_seq_hdr(void * buffer,unsigned size,unsigned * hdrlen)2438 bool omx_venc::dev_get_seq_hdr
2439 (
2440    void *buffer,
2441    unsigned size,
2442    unsigned *hdrlen
2443 )
2444 {
2445    ENTER_FUNC();
2446 
2447    SWVENC_STATUS Ret;
2448    SWVENC_OPBUFFER Buffer;
2449 
2450    Buffer.p_buffer = (unsigned char*) buffer;
2451    Buffer.size = size;
2452 
2453    Ret = swvenc_getsequenceheader(m_hSwVenc, &Buffer);
2454    if (Ret != SWVENC_S_SUCCESS)
2455    {
2456       DEBUG_PRINT_ERROR("%s, swvenc_getsequenceheader failed (%d)",
2457         __FUNCTION__, Ret);
2458       RETURN(false);
2459    }
2460 
2461    *hdrlen = Buffer.filled_length;
2462 
2463    RETURN(true);
2464 }
2465 
dev_get_capability_ltrcount(OMX_U32 * min,OMX_U32 * max,OMX_U32 * step_size)2466 bool omx_venc::dev_get_capability_ltrcount
2467 (
2468    OMX_U32 *min,
2469    OMX_U32 *max,
2470    OMX_U32 *step_size
2471 )
2472 {
2473     ENTER_FUNC();
2474 
2475     (void)min;
2476     (void)max;
2477     (void)step_size;
2478 
2479     DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported");
2480 
2481     RETURN(false);
2482 }
2483 
dev_get_vui_timing_info(OMX_U32 * enabled)2484 bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled)
2485 {
2486     ENTER_FUNC();
2487 
2488     (void)enabled;
2489     DEBUG_PRINT_ERROR("Get vui timing information is not supported");
2490 
2491     RETURN(false);
2492 }
2493 
dev_get_peak_bitrate(OMX_U32 * peakbitrate)2494 bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
2495 {
2496     //TBD: store the peak bitrate in class and return here;
2497     ENTER_FUNC();
2498 
2499     (void)peakbitrate;
2500     DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
2501 
2502     RETURN(false);
2503 }
2504 
dev_get_batch_size(OMX_U32 * size)2505 bool omx_venc::dev_get_batch_size(OMX_U32 *size)
2506 {
2507     ENTER_FUNC();
2508 
2509     (void)size;
2510 
2511     DEBUG_PRINT_ERROR("Get batch size is not supported");
2512 
2513     RETURN(false);
2514 }
2515 
dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)2516 OMX_ERRORTYPE omx_venc::dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2517 {
2518     ENTER_FUNC();
2519     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2520 
2521    if (profileLevelType == NULL)
2522    {
2523         DEBUG_PRINT_ERROR("p_profilelevel = NULL");
2524         return OMX_ErrorBadParameter;
2525    }
2526 
2527     if (profileLevelType->nPortIndex == 1) {
2528         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
2529         {
2530             if (profileLevelType->nProfileIndex == 0)
2531             {
2532                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2533                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
2534 
2535                 DEBUG_PRINT_HIGH("H.263 baseline profile, level 70");
2536             }
2537             else
2538             {
2539                 DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u",
2540                     (unsigned int)profileLevelType->nProfileIndex);
2541                 eRet = OMX_ErrorNoMore;
2542             }
2543         }
2544         else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
2545         {
2546             if (profileLevelType->nProfileIndex == 0)
2547             {
2548                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2549                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
2550 
2551                 DEBUG_PRINT_LOW("MPEG-4 simple profile, level 5");
2552             }
2553             else
2554             {
2555                 DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u",
2556                     (unsigned int)profileLevelType->nProfileIndex);
2557                  eRet = OMX_ErrorNoMore;
2558             }
2559         }
2560         else
2561         {
2562             DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level ret NoMore");
2563             eRet = OMX_ErrorNoMore;
2564         }
2565     }
2566     else
2567     {
2568         DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level should be queried on Input port only %u",
2569             (unsigned int)profileLevelType->nPortIndex);
2570         eRet = OMX_ErrorBadPortIndex;
2571     }
2572     return eRet;
2573 }
2574 
dev_get_supported_color_format(unsigned index,OMX_U32 * colorFormat)2575 bool omx_venc::dev_get_supported_color_format(unsigned index, OMX_U32 *colorFormat) {
2576     // we support two formats
2577     // index 0 - Venus flavour of YUV420SP
2578     // index 1 - opaque which internally maps to YUV420SP
2579     // index 2 - vannilla YUV420SP
2580     // this can be extended in the future
2581     int supportedFormats[] = {
2582         [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2583         [1] = QOMX_COLOR_FormatYVU420SemiPlanar,
2584         [2] = QOMX_COLOR_FormatAndroidOpaque,
2585         [3] = OMX_COLOR_FormatYUV420SemiPlanar,
2586     };
2587 
2588     if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
2589         return false;
2590     *colorFormat = supportedFormats[index];
2591     return true;
2592 }
2593 
dev_loaded_start()2594 bool omx_venc::dev_loaded_start()
2595 {
2596    ENTER_FUNC();
2597    RETURN(true);
2598 }
2599 
dev_loaded_stop()2600 bool omx_venc::dev_loaded_stop()
2601 {
2602    ENTER_FUNC();
2603    RETURN(true);
2604 }
2605 
dev_loaded_start_done()2606 bool omx_venc::dev_loaded_start_done()
2607 {
2608    ENTER_FUNC();
2609    RETURN(true);
2610 }
2611 
dev_loaded_stop_done()2612 bool omx_venc::dev_loaded_stop_done()
2613 {
2614    ENTER_FUNC();
2615    RETURN(true);
2616 }
2617 
is_streamon_done(OMX_U32 port)2618 bool omx_venc::is_streamon_done(OMX_U32 port)
2619 {
2620     if (PORT_INDEX_OUT <= port)
2621         ENTER_FUNC();
2622     RETURN(false);
2623 }
2624 
dev_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)2625 bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count,
2626         OMX_U32 *actual_buff_count,
2627         OMX_U32 *buff_size,
2628         OMX_U32 port)
2629 {
2630    ENTER_FUNC();
2631 
2632    bool bRet = true;
2633    OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2634 
2635    if (PORT_INDEX_IN == port)
2636    {
2637      PortDef = &m_sInPortDef;
2638    }
2639    else if (PORT_INDEX_OUT == port)
2640    {
2641      PortDef = &m_sOutPortDef;
2642    }
2643    else
2644    {
2645      DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2646      bRet = false;
2647    }
2648 
2649    if (true == bRet)
2650    {
2651       *min_buff_count = PortDef->nBufferCountMin;
2652       *actual_buff_count = PortDef->nBufferCountActual;
2653       *buff_size = PortDef->nBufferSize;
2654    }
2655 
2656    RETURN(true);
2657 }
2658 
dev_set_buf_req(OMX_U32 const * min_buff_count,OMX_U32 const * actual_buff_count,OMX_U32 const * buff_size,OMX_U32 port)2659 bool omx_venc::dev_set_buf_req
2660 (
2661    OMX_U32 const *min_buff_count,
2662    OMX_U32 const *actual_buff_count,
2663    OMX_U32 const *buff_size,
2664    OMX_U32 port
2665 )
2666 {
2667    ENTER_FUNC();
2668 
2669    SWVENC_STATUS Ret;
2670    OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2671 
2672    (void)min_buff_count;
2673    if (PORT_INDEX_IN == port)
2674    {
2675      PortDef = &m_sInPortDef;
2676    }
2677    else if (PORT_INDEX_OUT == port)
2678    {
2679      PortDef = &m_sOutPortDef;
2680    }
2681    else
2682    {
2683      DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2684      RETURN(false);
2685    }
2686 
2687    if (*actual_buff_count < PortDef->nBufferCountMin)
2688    {
2689       DEBUG_PRINT_ERROR("ERROR: %s, (actual,min) buffer count (%d, %d)",
2690          __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2691       RETURN(false);
2692    }
2693    if (false == meta_mode_enable)
2694    {
2695       if (*buff_size < PortDef->nBufferSize)
2696       {
2697           DEBUG_PRINT_ERROR("ERROR: %s, (new,old) buffer count (%d, %d)",
2698              __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2699           RETURN(false);
2700       }
2701    }
2702 
2703    RETURN(true);
2704 }
2705 
dev_is_video_session_supported(OMX_U32 width,OMX_U32 height)2706 bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height)
2707 {
2708    ENTER_FUNC();
2709 
2710    if ( (width * height < m_capability.min_width *  m_capability.min_height) ||
2711         (width * height > m_capability.max_width *  m_capability.max_height)
2712       )
2713    {
2714        DEBUG_PRINT_ERROR(
2715          "Unsupported Resolution WxH = (%u)x(%u) Supported Range = min (%d)x(%d) - max (%d)x(%d)",
2716          width, height,
2717          m_capability.min_width, m_capability.min_height,
2718          m_capability.max_width, m_capability.max_height);
2719        RETURN(false);
2720    }
2721 
2722    RETURN(true);
2723 }
2724 
dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE * buffer)2725 bool omx_venc::dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer)
2726 {
2727    ENTER_FUNC();
2728 
2729    (void)buffer;
2730    RETURN(true);
2731 }
dev_handle_output_extradata(void * buffer,int fd)2732 int omx_venc::dev_handle_output_extradata(void *buffer, int fd)
2733 {
2734    ENTER_FUNC();
2735 
2736    (void)buffer;
2737    (void)fd;
2738 
2739    RETURN(true);
2740 }
2741 
dev_handle_input_extradata(void * buffer,int fd,int index)2742 int omx_venc::dev_handle_input_extradata(void *buffer, int fd, int index)
2743 {
2744    ENTER_FUNC();
2745 
2746    (void)buffer;
2747    (void)fd;
2748    (void)index;
2749 
2750    RETURN(true);
2751 }
2752 
dev_set_extradata_cookie(void * buffer)2753 void omx_venc::dev_set_extradata_cookie(void *buffer)
2754 {
2755    ENTER_FUNC();
2756 
2757    (void)buffer;
2758 }
2759 
dev_set_format(int color)2760 int omx_venc::dev_set_format(int color)
2761 {
2762    ENTER_FUNC();
2763 
2764    (void)color;
2765 
2766    RETURN(true);
2767     //return handle->venc_set_format(color);
2768 }
2769 
dev_get_dimensions(OMX_U32 index,OMX_U32 * width,OMX_U32 * height)2770 bool omx_venc::dev_get_dimensions(OMX_U32 index, OMX_U32 *width, OMX_U32 *height)
2771 {
2772    ENTER_FUNC();
2773 
2774    (void)index;
2775    (void)width;
2776    (void)height;
2777 
2778    RETURN(true);
2779 }
2780 
dev_is_meta_mode()2781 bool omx_venc::dev_is_meta_mode()
2782 {
2783    ENTER_FUNC();
2784 
2785    RETURN(true);
2786 }
2787 
dev_is_avtimer_needed()2788 bool omx_venc::dev_is_avtimer_needed()
2789 {
2790    ENTER_FUNC();
2791 
2792    RETURN(true);
2793 }
2794 
dev_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2795 bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
2796                 OMX_U32 width, OMX_U32 height)
2797 {
2798     ENTER_FUNC();
2799 
2800     if(secure_session) {
2801         DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
2802         RETURN(false);
2803     }
2804     return swvenc_color_align(buffer, width,height);
2805 }
2806 
is_secure_session()2807 bool omx_venc::is_secure_session()
2808 {
2809     ENTER_FUNC();
2810 
2811     RETURN(secure_session);
2812 }
2813 
dev_get_output_log_flag()2814 bool omx_venc::dev_get_output_log_flag()
2815 {
2816     ENTER_FUNC();
2817 
2818     RETURN(m_debug.out_buffer_log == 1);
2819 }
2820 
dev_output_log_buffers(const char * buffer,int bufferlen,uint64_t ts)2821 int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen, uint64_t ts)
2822 {
2823     (void) ts;
2824     ENTER_FUNC();
2825 
2826     if (m_debug.out_buffer_log && !m_debug.outfile)
2827     {
2828         int size = 0;
2829         int width = m_sOutPortDef.format.video.nFrameWidth;
2830         int height = m_sOutPortDef.format.video.nFrameHeight;
2831         if(SWVENC_CODEC_MPEG4 == m_codec)
2832         {
2833            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2834               "%s/output_enc_%d_%d_%p.m4v",
2835               m_debug.log_loc, width, height, this);
2836         }
2837         else if(SWVENC_CODEC_H263 == m_codec)
2838         {
2839            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2840               "%s/output_enc_%d_%d_%p.263",
2841               m_debug.log_loc, width, height, this);
2842         }
2843         if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2844         {
2845            DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
2846                               m_debug.outfile_name, size);
2847            RETURN(-1);
2848         }
2849         DEBUG_PRINT_LOW("output filename = %s", m_debug.outfile_name);
2850         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
2851         if (!m_debug.outfile)
2852         {
2853            DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
2854                              m_debug.outfile_name, errno);
2855            m_debug.outfile_name[0] = '\0';
2856            RETURN(-1);
2857         }
2858     }
2859     if (m_debug.outfile && buffer && bufferlen)
2860     {
2861         DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2862         fwrite(buffer, bufferlen, 1, m_debug.outfile);
2863     }
2864 
2865     RETURN(0);
2866 }
2867 
swvenc_input_log_buffers(const char * buffer,int bufferlen)2868 int omx_venc::swvenc_input_log_buffers(const char *buffer, int bufferlen)
2869 {
2870    int width = m_sInPortDef.format.video.nFrameWidth;
2871    int height = m_sInPortDef.format.video.nFrameHeight;
2872    int stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12, width);
2873    int scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12, height);
2874    char *temp = (char*)buffer;
2875 
2876    if (!m_debug.infile)
2877    {
2878        int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX,
2879                       "%s/input_enc_%d_%d_%p.yuv",
2880                       m_debug.log_loc, width, height, this);
2881        if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2882        {
2883            DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
2884                               m_debug.infile_name, size);
2885            RETURN(-1);
2886        }
2887        DEBUG_PRINT_LOW("input filename = %s", m_debug.infile_name);
2888        m_debug.infile = fopen (m_debug.infile_name, "ab");
2889        if (!m_debug.infile)
2890        {
2891            DEBUG_PRINT_HIGH("Failed to open input file: %s for logging",
2892               m_debug.infile_name);
2893            m_debug.infile_name[0] = '\0';
2894            RETURN(-1);
2895        }
2896    }
2897    if (m_debug.infile && buffer && bufferlen)
2898    {
2899        DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2900        for (int i = 0; i < height; i++)
2901        {
2902           fwrite(temp, width, 1, m_debug.infile);
2903           temp += stride;
2904        }
2905        temp = (char*)(buffer + (stride * scanlines));
2906        for(int i = 0; i < height/2; i++)
2907        {
2908           fwrite(temp, width, 1, m_debug.infile);
2909           temp += stride;
2910       }
2911    }
2912 
2913    RETURN(0);
2914 }
2915 
swvenc_input_log_rotated_buffers(const char * buffer,int bufferlen)2916 int omx_venc::swvenc_input_log_rotated_buffers(const char *buffer, int bufferlen)
2917 {
2918    int width = m_sInPortDef.format.video.nFrameWidth;
2919    int height = m_sInPortDef.format.video.nFrameHeight;
2920    if (m_bIsInFlipDone) {
2921        auto v = width;
2922        width = height;
2923        height = v;
2924    }
2925    int stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12, width);
2926    int scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12, height);
2927    char *temp = (char*)buffer;
2928 
2929    if (!m_debug.inrotatedfile)
2930    {
2931        int size = snprintf(m_debug.inrotatedfile_name, PROPERTY_VALUE_MAX,
2932                       "%s/input_enc_rotated_%d_%d_%p.yuv",
2933                       m_debug.log_loc, width, height, this);
2934        if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2935        {
2936            DEBUG_PRINT_ERROR("Failed to open input rotated file: %s for logging size:%d",
2937                               m_debug.inrotatedfile_name, size);
2938            RETURN(-1);
2939        }
2940        DEBUG_PRINT_LOW("input rotated filename = %s", m_debug.inrotatedfile_name);
2941        m_debug.inrotatedfile = fopen (m_debug.inrotatedfile_name, "ab");
2942        if (!m_debug.inrotatedfile)
2943        {
2944            DEBUG_PRINT_HIGH("Failed to open input rotated file: %s for logging",
2945               m_debug.inrotatedfile_name);
2946            m_debug.inrotatedfile_name[0] = '\0';
2947            RETURN(-1);
2948        }
2949    }
2950    if (m_debug.inrotatedfile && buffer && bufferlen)
2951    {
2952        DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2953        for (int i = 0; i < height; i++)
2954        {
2955           fwrite(temp, width, 1, m_debug.inrotatedfile);
2956           temp += stride;
2957        }
2958        temp = (char*)(buffer + (stride * scanlines));
2959        for(int i = 0; i < height/2; i++)
2960        {
2961           fwrite(temp, width, 1, m_debug.inrotatedfile);
2962           temp += stride;
2963       }
2964    }
2965 
2966    RETURN(0);
2967 }
2968 
dev_extradata_log_buffers(char * buffer,int index,bool input)2969 int omx_venc::dev_extradata_log_buffers(char *buffer, int index, bool input)
2970 {
2971    ENTER_FUNC();
2972 
2973    (void)buffer;
2974    (void)index;
2975    (void)input;
2976 
2977    RETURN(true);
2978     //return handle->venc_extradata_log_buffers(buffer);
2979 }
2980 
swvenc_get_buffer_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 * buff_alignment,OMX_U32 port)2981 SWVENC_STATUS omx_venc::swvenc_get_buffer_req
2982 (
2983    OMX_U32 *min_buff_count,
2984    OMX_U32 *actual_buff_count,
2985    OMX_U32 *buff_size,
2986    OMX_U32 *buff_alignment,
2987    OMX_U32 port
2988 )
2989 {
2990     ENTER_FUNC();
2991 
2992     SWVENC_PROPERTY Prop;
2993     SWVENC_STATUS Ret;
2994     OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2995 
2996     Prop.id = SWVENC_PROPERTY_ID_BUFFER_REQ;
2997     if (PORT_INDEX_IN == port)
2998     {
2999       Prop.info.buffer_req.type = SWVENC_BUFFER_INPUT;
3000     }
3001     else if (PORT_INDEX_OUT == port)
3002     {
3003       Prop.info.buffer_req.type = SWVENC_BUFFER_OUTPUT;
3004     }
3005     else
3006     {
3007       DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
3008       RETURN(SWVENC_S_INVALID_PARAMETERS);
3009     }
3010 
3011     Ret = swvenc_getproperty(m_hSwVenc, &Prop);
3012     if (Ret != SWVENC_S_SUCCESS)
3013     {
3014        DEBUG_PRINT_ERROR("ERROR: %s, swvenc_setproperty failed (%d)", __FUNCTION__,
3015           Ret);
3016        RETURN(SWVENC_S_INVALID_PARAMETERS);
3017     }
3018 
3019     *buff_size = Prop.info.buffer_req.size;
3020     *min_buff_count = Prop.info.buffer_req.mincount;
3021     *actual_buff_count = Prop.info.buffer_req.mincount;
3022     *buff_alignment = Prop.info.buffer_req.alignment;
3023 
3024     RETURN(Ret);
3025 }
3026 
swvenc_empty_buffer_done_cb(SWVENC_HANDLE swvenc,SWVENC_IPBUFFER * p_ipbuffer,void * p_client)3027 SWVENC_STATUS omx_venc::swvenc_empty_buffer_done_cb
3028 (
3029     SWVENC_HANDLE    swvenc,
3030     SWVENC_IPBUFFER *p_ipbuffer,
3031     void            *p_client
3032 )
3033 {
3034     ENTER_FUNC();
3035 
3036     (void)swvenc;
3037     SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3038     omx_venc *omx = reinterpret_cast<omx_venc*>(p_client);
3039 
3040     if (p_ipbuffer == NULL)
3041     {
3042         eRet = SWVENC_S_FAILURE;
3043     }
3044     else
3045     {
3046         omx->swvenc_empty_buffer_done(p_ipbuffer);
3047     }
3048     return eRet;
3049 }
3050 
swvenc_empty_buffer_done(SWVENC_IPBUFFER * p_ipbuffer)3051 SWVENC_STATUS omx_venc::swvenc_empty_buffer_done
3052 (
3053     SWVENC_IPBUFFER *p_ipbuffer
3054 )
3055 {
3056     SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3057     OMX_ERRORTYPE error = OMX_ErrorNone;
3058     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3059 
3060     //omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3061     if (!p_ipbuffer) {
3062         DEBUG_PRINT_ERROR("EBD: null buffer");
3063         return SWVENC_S_NULL_POINTER;
3064     }
3065 
3066     omxhdr = (OMX_BUFFERHEADERTYPE*)p_ipbuffer->p_client_data;
3067 
3068     DEBUG_PRINT_LOW("EBD: clientData (%p)", p_ipbuffer->p_client_data);
3069 
3070     if ( (omxhdr == NULL) ||
3071          ( ((OMX_U32)(omxhdr - m_inp_mem_ptr) >m_sInPortDef.nBufferCountActual) &&
3072            ((OMX_U32)(omxhdr - meta_buffer_hdr) >m_sInPortDef.nBufferCountActual)
3073          )
3074        )
3075     {
3076         omxhdr = NULL;
3077         error = OMX_ErrorUndefined;
3078     }
3079 
3080     if (m_pIpbuffers != nullptr) {
3081         int index = omxhdr - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
3082         DEBUG_PRINT_HIGH("restore ipbuffer[p_buffer(%p), size(%d), filled_length(%d)] to original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]",
3083                 p_ipbuffer->p_buffer,
3084                 p_ipbuffer->size,
3085                 p_ipbuffer->filled_length,
3086                 m_pIpbuffers[index].p_buffer,
3087                 m_pIpbuffers[index].size,
3088                 m_pIpbuffers[index].filled_length);
3089         p_ipbuffer->size = m_pIpbuffers[index].size;
3090         p_ipbuffer->filled_length = m_pIpbuffers[index].filled_length;
3091         p_ipbuffer->p_buffer = m_pIpbuffers[index].p_buffer;
3092     }
3093 
3094     if (omxhdr != NULL)
3095     {
3096         // unmap the input buffer->pBuffer
3097         omx_release_meta_buffer(omxhdr);
3098 #ifdef _ANDROID_ICS_
3099         if (meta_mode_enable)
3100         {
3101            LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
3102            unsigned int size = 0;
3103            meta_buf = (LEGACY_CAM_METADATA_TYPE *)omxhdr->pBuffer;
3104            if (meta_buf)
3105            {
3106               if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
3107               {
3108                   size = meta_buf->meta_handle->data[2];
3109               }
3110               else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
3111               {
3112                   VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)omxhdr->pBuffer;
3113                   private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
3114                   size = handle->size;
3115               }
3116            }
3117 
3118            DEBUG_PRINT_HIGH("Unmapping pBuffer <%p> size <%d>", p_ipbuffer->p_buffer, size);
3119            if (-1 == munmap(p_ipbuffer->p_buffer, size))
3120                DEBUG_PRINT_HIGH("Unmap failed");
3121         }
3122 #endif
3123         post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_EBD);
3124     }
3125     RETURN(eRet);
3126 }
3127 
swvenc_fill_buffer_done_cb(SWVENC_HANDLE swvenc,SWVENC_OPBUFFER * p_opbuffer,void * p_client)3128 SWVENC_STATUS omx_venc::swvenc_fill_buffer_done_cb
3129 (
3130     SWVENC_HANDLE    swvenc,
3131     SWVENC_OPBUFFER *p_opbuffer,
3132     void            *p_client
3133 )
3134 {
3135     ENTER_FUNC();
3136 
3137     SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3138     OMX_ERRORTYPE error = OMX_ErrorNone;
3139     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3140     omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3141 
3142     (void)swvenc;
3143 
3144     if (p_opbuffer != NULL)
3145     {
3146         omxhdr = (OMX_BUFFERHEADERTYPE*)p_opbuffer->p_client_data;
3147     }
3148 
3149     if ( (p_opbuffer != NULL) &&
3150          ((OMX_U32)(omxhdr - omx->m_out_mem_ptr)  < omx->m_sOutPortDef.nBufferCountActual)
3151        )
3152     {
3153         DEBUG_PRINT_LOW("FBD: clientData (%p) buffer (%p) filled_lengh (%d) flags (0x%x) ts (%lld)",
3154           p_opbuffer->p_client_data,
3155           p_opbuffer->p_buffer,
3156           p_opbuffer->filled_length,
3157           p_opbuffer->flags,
3158           p_opbuffer->timestamp);
3159 
3160         if (p_opbuffer->filled_length <=  omxhdr->nAllocLen)
3161         {
3162             omxhdr->pBuffer = p_opbuffer->p_buffer;
3163             omxhdr->nFilledLen = p_opbuffer->filled_length;
3164             omxhdr->nOffset = 0;
3165             omxhdr->nTimeStamp = p_opbuffer->timestamp;
3166             omxhdr->nFlags = 0;
3167             if (SWVENC_FRAME_TYPE_I == p_opbuffer->frame_type)
3168             {
3169                omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
3170             }
3171             if (SWVENC_FLAG_EOS & p_opbuffer->flags)
3172             {
3173                omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
3174             }
3175             if(omxhdr->nFilledLen)
3176             {
3177                omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
3178             }
3179             DEBUG_PRINT_LOW("o/p flag = 0x%x", omxhdr->nFlags);
3180 
3181             /* Use buffer case */
3182             if (omx->output_use_buffer && !omx->m_use_output_pmem)
3183             {
3184                 DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
3185                 memcpy( omxhdr->pBuffer,
3186                         (p_opbuffer->p_buffer),
3187                         p_opbuffer->filled_length );
3188             }
3189         }
3190         else
3191         {
3192             omxhdr->nFilledLen = 0;
3193         }
3194 
3195     }
3196     else
3197     {
3198         omxhdr = NULL;
3199         error = OMX_ErrorUndefined;
3200     }
3201 
3202     omx->post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_FBD);
3203 
3204     RETURN(eRet);
3205 }
3206 
swvenc_handle_event_cb(SWVENC_HANDLE swvenc,SWVENC_EVENT event,void * p_client)3207 SWVENC_STATUS omx_venc::swvenc_handle_event_cb
3208 (
3209     SWVENC_HANDLE swvenc,
3210     SWVENC_EVENT  event,
3211     void         *p_client
3212 )
3213 {
3214     ENTER_FUNC();
3215 
3216     SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3217     omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3218 
3219     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3220 
3221     (void)swvenc;
3222 
3223     if (omx == NULL || p_client == NULL)
3224     {
3225         DEBUG_PRINT_ERROR("ERROR: %s invalid i/p params", __FUNCTION__);
3226         RETURN(SWVENC_S_NULL_POINTER);
3227     }
3228 
3229     DEBUG_PRINT_LOW("swvenc_handle_event_cb - event = %d", event);
3230 
3231     switch (event)
3232     {
3233         case SWVENC_EVENT_FLUSH_DONE:
3234         {
3235            DEBUG_PRINT_ERROR("SWVENC_EVENT_FLUSH_DONE input_flush_progress %d output_flush_progress %d",
3236             omx->input_flush_progress, omx->output_flush_progress);
3237            if (omx->input_flush_progress)
3238            {
3239                omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
3240                   OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
3241            }
3242            if (omx->output_flush_progress)
3243            {
3244                omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
3245                   OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
3246            }
3247            break;
3248         }
3249 
3250         case SWVENC_EVENT_FATAL_ERROR:
3251         {
3252            DEBUG_PRINT_ERROR("ERROR: SWVENC_EVENT_FATAL_ERROR");
3253            omx->omx_report_error();
3254            break;
3255         }
3256 
3257         default:
3258             DEBUG_PRINT_HIGH("Unknown event received : %d", event);
3259             break;
3260     }
3261 
3262     RETURN(eRet);
3263 }
3264 
swvenc_set_rc_mode(OMX_VIDEO_CONTROLRATETYPE eControlRate)3265 SWVENC_STATUS omx_venc::swvenc_set_rc_mode
3266 (
3267     OMX_VIDEO_CONTROLRATETYPE eControlRate
3268 )
3269 {
3270     ENTER_FUNC();
3271 
3272     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3273     SWVENC_RC_MODE rc_mode;
3274     SWVENC_PROPERTY Prop;
3275 
3276     switch (eControlRate)
3277     {
3278         case OMX_Video_ControlRateDisable:
3279             rc_mode = SWVENC_RC_MODE_NONE;
3280             break;
3281         case OMX_Video_ControlRateVariableSkipFrames:
3282             rc_mode = SWVENC_RC_MODE_VBR_VFR;
3283             break;
3284         case OMX_Video_ControlRateVariable:
3285             rc_mode = SWVENC_RC_MODE_VBR_CFR;
3286             break;
3287         case OMX_Video_ControlRateConstantSkipFrames:
3288             rc_mode = SWVENC_RC_MODE_CBR_VFR;
3289             break;
3290         case OMX_Video_ControlRateConstant:
3291             rc_mode = SWVENC_RC_MODE_CBR_CFR;
3292             break;
3293         default:
3294             DEBUG_PRINT_ERROR("ERROR: UNKNOWN RC MODE");
3295             Ret = SWVENC_S_FAILURE;
3296             break;
3297     }
3298 
3299     if (SWVENC_S_SUCCESS == Ret)
3300     {
3301         Prop.id = SWVENC_PROPERTY_ID_RC_MODE;
3302         Prop.info.rc_mode = rc_mode;
3303         Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3304         if (Ret != SWVENC_S_SUCCESS)
3305         {
3306            DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3307              __FUNCTION__, Ret);
3308            RETURN(SWVENC_S_FAILURE);
3309         }
3310     }
3311 
3312     RETURN(Ret);
3313 }
3314 
swvenc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)3315 SWVENC_STATUS omx_venc::swvenc_set_profile_level
3316 (
3317     OMX_U32 eProfile,
3318     OMX_U32 eLevel
3319 )
3320 {
3321     ENTER_FUNC();
3322 
3323     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3324     SWVENC_PROPERTY Prop;
3325     SWVENC_PROFILE Profile;
3326     SWVENC_LEVEL Level;
3327 
3328     /* set the profile */
3329     if (SWVENC_CODEC_MPEG4 == m_codec)
3330     {
3331        switch (eProfile)
3332        {
3333           case OMX_VIDEO_MPEG4ProfileSimple:
3334              Profile.mpeg4 = SWVENC_PROFILE_MPEG4_SIMPLE;
3335              break;
3336           case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
3337              Profile.mpeg4 = SWVENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
3338              break;
3339           default:
3340              DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
3341              Ret = SWVENC_S_FAILURE;
3342              break;
3343        }
3344        switch (eLevel)
3345        {
3346           case OMX_VIDEO_MPEG4Level0:
3347              Level.mpeg4 = SWVENC_LEVEL_MPEG4_0;
3348              break;
3349           case OMX_VIDEO_MPEG4Level0b:
3350              Level.mpeg4 = SWVENC_LEVEL_MPEG4_0B;
3351              break;
3352           case OMX_VIDEO_MPEG4Level1:
3353              Level.mpeg4 = SWVENC_LEVEL_MPEG4_1;
3354              break;
3355           case OMX_VIDEO_MPEG4Level2:
3356              Level.mpeg4 = SWVENC_LEVEL_MPEG4_2;
3357              break;
3358           case OMX_VIDEO_MPEG4Level3:
3359              Level.mpeg4 = SWVENC_LEVEL_MPEG4_3;
3360              break;
3361           case OMX_VIDEO_MPEG4Level4:
3362              Level.mpeg4 = SWVENC_LEVEL_MPEG4_4;
3363              break;
3364           case OMX_VIDEO_MPEG4Level4a:
3365              Level.mpeg4 = SWVENC_LEVEL_MPEG4_4A;
3366              break;
3367           case OMX_VIDEO_MPEG4Level5:
3368              Level.mpeg4 = SWVENC_LEVEL_MPEG4_5;
3369              break;
3370           default:
3371              DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
3372              Ret = SWVENC_S_FAILURE;
3373              break;
3374        }
3375     }
3376     else if (SWVENC_CODEC_H263 == m_codec)
3377     {
3378        switch (eProfile)
3379        {
3380           case OMX_VIDEO_H263ProfileBaseline:
3381              Profile.h263 = SWVENC_PROFILE_H263_BASELINE;
3382              break;
3383           default:
3384              DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
3385              Ret = SWVENC_S_FAILURE;
3386              break;
3387        }
3388        switch (eLevel)
3389        {
3390           case OMX_VIDEO_H263Level10:
3391              Level.h263 = SWVENC_LEVEL_H263_10;
3392              break;
3393           case OMX_VIDEO_H263Level20:
3394              Level.h263 = SWVENC_LEVEL_H263_20;
3395              break;
3396           case OMX_VIDEO_H263Level30:
3397              Level.h263 = SWVENC_LEVEL_H263_30;
3398              break;
3399           case OMX_VIDEO_H263Level40:
3400              Level.h263 = SWVENC_LEVEL_H263_40;
3401              break;
3402           case OMX_VIDEO_H263Level45:
3403              Level.h263 = SWVENC_LEVEL_H263_45;
3404              break;
3405           case OMX_VIDEO_H263Level50:
3406              Level.h263 = SWVENC_LEVEL_H263_50;
3407              break;
3408           case OMX_VIDEO_H263Level60:
3409              Level.h263 = SWVENC_LEVEL_H263_60;
3410              break;
3411           case OMX_VIDEO_H263Level70:
3412              Level.h263 = SWVENC_LEVEL_H263_70;
3413              break;
3414           default:
3415              DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
3416              Ret = SWVENC_S_FAILURE;
3417              break;
3418        }
3419     }
3420     else
3421     {
3422       DEBUG_PRINT_ERROR("ERROR: UNSUPPORTED CODEC");
3423       Ret = SWVENC_S_FAILURE;
3424     }
3425 
3426     if (SWVENC_S_SUCCESS == Ret)
3427     {
3428        Prop.id = SWVENC_PROPERTY_ID_PROFILE;
3429        Prop.info.profile = Profile;
3430 
3431        /* set the profile */
3432        Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3433        if (Ret != SWVENC_S_SUCCESS)
3434        {
3435           DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3436             __FUNCTION__, Ret);
3437           RETURN(SWVENC_S_FAILURE);
3438        }
3439 
3440        /* set the level */
3441        Prop.id = SWVENC_PROPERTY_ID_LEVEL;
3442        Prop.info.level = Level;
3443 
3444        Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3445        if (Ret != SWVENC_S_SUCCESS)
3446        {
3447           DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3448             __FUNCTION__, Ret);
3449           RETURN(SWVENC_S_FAILURE);
3450        }
3451     }
3452 
3453     RETURN(Ret);
3454 }
3455 
swvenc_set_intra_refresh(OMX_VIDEO_PARAM_INTRAREFRESHTYPE * IntraRefresh)3456 SWVENC_STATUS omx_venc::swvenc_set_intra_refresh
3457 (
3458     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh
3459 )
3460 {
3461    ENTER_FUNC();
3462 
3463    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3464    SWVENC_IR_CONFIG ir_config;
3465    SWVENC_PROPERTY Prop;
3466 
3467    switch (IntraRefresh->eRefreshMode)
3468    {
3469       case OMX_VIDEO_IntraRefreshCyclic:
3470         Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC;
3471         break;
3472       case OMX_VIDEO_IntraRefreshAdaptive:
3473          Prop.info.ir_config.mode = SWVENC_IR_MODE_ADAPTIVE;
3474         break;
3475       case OMX_VIDEO_IntraRefreshBoth:
3476          Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC_ADAPTIVE;
3477         break;
3478       case OMX_VIDEO_IntraRefreshRandom:
3479          Prop.info.ir_config.mode = SWVENC_IR_MODE_RANDOM;
3480         break;
3481       default:
3482          DEBUG_PRINT_ERROR("ERROR: UNKNOWN INTRA REFRESH MODE");
3483          Ret = SWVENC_S_FAILURE;
3484          break;
3485    }
3486 
3487    if (SWVENC_S_SUCCESS == Ret)
3488    {
3489        Prop.id = SWVENC_PROPERTY_ID_IR_CONFIG;
3490        Prop.info.ir_config.cir_mbs = IntraRefresh->nCirMBs;
3491 
3492        Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3493        if (Ret != SWVENC_S_SUCCESS)
3494        {
3495           DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3496             __FUNCTION__, Ret);
3497           Ret = SWVENC_S_FAILURE;
3498        }
3499    }
3500 
3501    RETURN(Ret);
3502 }
3503 
swvenc_set_frame_rate(OMX_U32 nFrameRate)3504 SWVENC_STATUS omx_venc::swvenc_set_frame_rate
3505 (
3506     OMX_U32 nFrameRate
3507 )
3508 {
3509    ENTER_FUNC();
3510 
3511    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3512    SWVENC_PROPERTY Prop;
3513 
3514    Prop.id = SWVENC_PROPERTY_ID_FRAME_RATE;
3515    Prop.info.frame_rate = nFrameRate;
3516 
3517    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3518    if (Ret != SWVENC_S_SUCCESS)
3519    {
3520       DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3521         __FUNCTION__, Ret);
3522       Ret = SWVENC_S_FAILURE;
3523    }
3524 
3525    RETURN(Ret);
3526 }
3527 
swvenc_set_bit_rate(OMX_U32 nTargetBitrate)3528 SWVENC_STATUS omx_venc::swvenc_set_bit_rate
3529 (
3530     OMX_U32 nTargetBitrate
3531 )
3532 {
3533    ENTER_FUNC();
3534 
3535    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3536    SWVENC_PROPERTY Prop;
3537 
3538    Prop.id = SWVENC_PROPERTY_ID_TARGET_BITRATE;
3539    Prop.info.target_bitrate = nTargetBitrate;
3540 
3541    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3542    if (Ret != SWVENC_S_SUCCESS)
3543    {
3544       DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3545         __FUNCTION__, Ret);
3546       Ret = SWVENC_S_FAILURE;
3547    }
3548 
3549    RETURN(Ret);
3550 }
3551 
swvenc_set_intra_period(OMX_U32 nPFrame,OMX_U32 nBFrame)3552 SWVENC_STATUS omx_venc::swvenc_set_intra_period
3553 (
3554     OMX_U32 nPFrame,
3555     OMX_U32 nBFrame
3556 )
3557 {
3558    ENTER_FUNC();
3559 
3560    SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3561    SWVENC_PROPERTY Prop;
3562 
3563    Prop.id = SWVENC_PROPERTY_ID_INTRA_PERIOD;
3564    Prop.info.intra_period.pframes = nPFrame;
3565    Prop.info.intra_period.bframes = nBFrame;
3566 
3567    Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3568    if (Ret != SWVENC_S_SUCCESS)
3569    {
3570       DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3571         __FUNCTION__, Ret);
3572       Ret = SWVENC_S_FAILURE;
3573    }
3574 
3575    RETURN(Ret);
3576 }
3577 
swvenc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3578 bool omx_venc::swvenc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
3579                         OMX_U32 height)
3580 {
3581     OMX_U32 y_stride,y_scanlines,uv_scanlines,plane_size_y,plane_size_uv,src_chroma_offset;
3582     y_stride = SWVENC_Y_STRIDE(COLOR_FMT_NV12,width);
3583     y_scanlines = SWVENC_Y_SCANLINES(COLOR_FMT_NV12,height);
3584     src_chroma_offset = width * height;
3585     OMX_U32 buffersize = SWVENC_BUFFER_SIZE(COLOR_FMT_NV12,width,height);
3586     if (buffer->nAllocLen >= buffersize) {
3587         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3588         //Do chroma first, so that we can convert it in-place
3589         src_buf += width * height;
3590         dst_buf += y_stride * y_scanlines;
3591         for (int line = height / 2 - 1; line >= 0; --line) {
3592             memmove(dst_buf + line * y_stride,
3593                     src_buf + line * width,
3594                     width);
3595         }
3596 
3597         dst_buf = src_buf = buffer->pBuffer;
3598         //Copy the Y next
3599         for (int line = height - 1; line > 0; --line) {
3600             memmove(dst_buf + line * y_stride,
3601                     src_buf + line * width,
3602                     width);
3603         }
3604     } else {
3605         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3606                 Insufficient bufferLen=%u v/s Required=%u",
3607                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3608                 buffersize);
3609         return false;
3610     }
3611 
3612     return true;
3613 }
3614 
swvenc_set_color_format(OMX_COLOR_FORMATTYPE color_format)3615 SWVENC_STATUS omx_venc::swvenc_set_color_format
3616 (
3617    OMX_COLOR_FORMATTYPE color_format
3618 )
3619 {
3620     ENTER_FUNC();
3621     SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3622     SWVENC_COLOR_FORMAT swvenc_color_format;
3623     SWVENC_PROPERTY Prop;
3624     if (color_format == ((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m))
3625     {
3626         DEBUG_PRINT_ERROR("QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m");
3627         swvenc_color_format = SWVENC_COLOR_FORMAT_NV12;
3628         Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
3629         Prop.info.frame_attributes.stride_luma = SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sOutPortDef.format.video.nFrameWidth);
3630         Prop.info.frame_attributes.stride_chroma = SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sOutPortDef.format.video.nFrameWidth);
3631         Prop.info.frame_attributes.offset_luma = 0;
3632         Prop.info.frame_attributes.offset_chroma = ((SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sOutPortDef.format.video.nFrameWidth)) * (SWVENC_Y_SCANLINES(COLOR_FMT_NV12, m_sOutPortDef.format.video.nFrameHeight)));
3633         Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3634         if (Ret != SWVENC_S_SUCCESS)
3635         {
3636             DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3637                 __FUNCTION__, Ret);
3638             Ret = SWVENC_S_FAILURE;
3639         }
3640     }
3641     else if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
3642     {
3643         swvenc_color_format = SWVENC_COLOR_FORMAT_NV12;
3644         Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
3645         Prop.info.frame_attributes.stride_luma = SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sInPortDef.format.video.nFrameWidth);
3646         Prop.info.frame_attributes.stride_chroma = SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sInPortDef.format.video.nFrameWidth);
3647         Prop.info.frame_attributes.offset_luma = 0;
3648         Prop.info.frame_attributes.offset_chroma = ((SWVENC_Y_STRIDE(COLOR_FMT_NV12, m_sInPortDef.format.video.nFrameWidth)) * (SWVENC_Y_SCANLINES(COLOR_FMT_NV12, m_sInPortDef.format.video.nFrameHeight)));
3649         Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3650         if (Ret != SWVENC_S_SUCCESS)
3651         {
3652             DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3653                 __FUNCTION__, Ret);
3654             Ret = SWVENC_S_FAILURE;
3655         }
3656     }
3657     else if (color_format == ((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatYVU420SemiPlanar))
3658     {
3659         swvenc_color_format = SWVENC_COLOR_FORMAT_NV21;
3660         Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
3661         Prop.info.frame_attributes.stride_luma = ALIGN(m_sInPortDef.format.video.nFrameWidth,16);
3662         Prop.info.frame_attributes.stride_chroma = ALIGN(m_sInPortDef.format.video.nFrameWidth,16);
3663         Prop.info.frame_attributes.offset_luma = 0;
3664         Prop.info.frame_attributes.offset_chroma = ((ALIGN(m_sInPortDef.format.video.nFrameWidth,16)) * (ALIGN(m_sInPortDef.format.video.nFrameHeight,16)));
3665         Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3666         if (Ret != SWVENC_S_SUCCESS)
3667         {
3668             DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3669                 __FUNCTION__, Ret);
3670             Ret = SWVENC_S_FAILURE;
3671         }
3672     }
3673     else if (color_format == ((OMX_COLOR_FORMATTYPE) HAL_PIXEL_FORMAT_NV21_ZSL))
3674     {
3675         DEBUG_PRINT_ERROR("HAL_PIXEL_FORMAT_NV21_ZSL");
3676         swvenc_color_format = SWVENC_COLOR_FORMAT_NV21;
3677         Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
3678         Prop.info.frame_attributes.stride_luma = SWVENC_Y_STRIDE(COLOR_FMT_NV12_ZSL, m_sInPortDef.format.video.nFrameWidth);
3679         Prop.info.frame_attributes.stride_chroma = SWVENC_Y_STRIDE(COLOR_FMT_NV12_ZSL, m_sInPortDef.format.video.nFrameWidth);
3680         Prop.info.frame_attributes.offset_luma = 0;
3681         Prop.info.frame_attributes.offset_chroma = ((SWVENC_Y_STRIDE(COLOR_FMT_NV12_ZSL, m_sInPortDef.format.video.nFrameWidth)) * (SWVENC_Y_SCANLINES(COLOR_FMT_NV12_ZSL, m_sInPortDef.format.video.nFrameHeight)));
3682         Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3683         if (Ret != SWVENC_S_SUCCESS)
3684         {
3685             DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3686                 __FUNCTION__, Ret);
3687             Ret = SWVENC_S_FAILURE;
3688         }
3689     }
3690     else
3691     {
3692         DEBUG_PRINT_ERROR("%s: color_format %d invalid",__FUNCTION__,color_format);
3693         RETURN(SWVENC_S_FAILURE);
3694     }
3695     /* set the input color format */
3696     Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
3697     Prop.info.color_format = swvenc_color_format;
3698     Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3699     if (Ret != SWVENC_S_SUCCESS)
3700     {
3701         DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3702             __FUNCTION__, Ret);
3703         Ret = SWVENC_S_FAILURE;
3704     }
3705     RETURN(Ret);
3706 }
3707 
3708 // don't use init_vendor_extensions() from omx_video_extensions.hpp, sw component doesn't support
3709 // all the vendor extensions like hw component
init_sw_vendor_extensions(VendorExtensionStore & store)3710 void omx_venc::init_sw_vendor_extensions(VendorExtensionStore &store) {
3711     ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput)
3712     ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32)
3713 
3714     ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps,
3715             OMX_DirOutput)
3716     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
3717 
3718     ADD_EXTENSION("qti-ext-enc-bitrate-mode", OMX_IndexParamVideoBitrate, OMX_DirOutput)
3719     ADD_PARAM_END("value", OMX_AndroidVendorValueInt32)
3720 }
3721 
3722