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