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