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