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