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