1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 --------------------------------------------------------------------------*/
29
30 #include "video_encoder_device_v4l2.h"
31 #include "omx_video_encoder.h"
32
33 #undef LOG_TAG
34 #define LOG_TAG "OMX-VENC: venc_dev"
35
venc_get_consumer_usage(OMX_U32 * usage)36 void venc_dev::venc_get_consumer_usage(OMX_U32* usage)
37 {
38
39 OMX_U32 eProfile = 0;
40 bool hevc = venc_get_hevc_profile(&eProfile);
41
42 /* Initialize to zero & update as per required color format */
43 *usage = 0;
44
45 /* Configure UBWC as default if target supports */
46 #ifdef _UBWC_
47 *usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
48 #endif
49
50 if (hevc &&
51 (eProfile == (OMX_U32)OMX_VIDEO_HEVCProfileMain10HDR10 ||
52 eProfile == (OMX_U32)OMX_VIDEO_HEVCProfileMain10 ||
53 eProfile == (OMX_U32)OMX_VIDEO_HEVCProfileMain10HDR10Plus)) {
54 DEBUG_PRINT_INFO("Setting 10-bit consumer usage bits");
55 *usage |= GRALLOC_USAGE_PRIVATE_10BIT_VIDEO;
56 if (mUseLinearColorFormat & REQUEST_LINEAR_COLOR_10_BIT) {
57 *usage &= ~GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
58 DEBUG_PRINT_INFO("Clear UBWC consumer usage bits as 10-bit linear color requested");
59 }
60 } else if (mUseLinearColorFormat & REQUEST_LINEAR_COLOR_8_BIT ||
61 m_codec == OMX_VIDEO_CodingImageHEIC) {
62 *usage &= ~GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
63 DEBUG_PRINT_INFO("Clear UBWC consumer usage bits as 8-bit linear color requested");
64 }
65
66 DEBUG_PRINT_INFO("venc_get_consumer_usage 0x%x", *usage);
67 }
68
venc_set_config(void * configData,OMX_INDEXTYPE index)69 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
70 {
71
72 if (is_streamon_done(PORT_INDEX_IN)) {
73 if (venc_store_dynamic_config(index, configData)) {
74 DEBUG_PRINT_HIGH("dynamic config %#X successfully stored.", index);
75 return true;
76 }
77
78 /* If failed, try to handle the dynamic config immediately */
79 DEBUG_PRINT_ERROR("Store dynamic config %#X failed", index);
80 }
81
82 DEBUG_PRINT_LOW("Inside venc_set_config");
83
84 switch ((int)index) {
85 case OMX_IndexConfigVideoBitrate:
86 {
87 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
88 configData;
89 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
90 if (!venc_config_bitrate(bit_rate))
91 return false;
92
93 break;
94 }
95 case OMX_IndexConfigVideoFramerate:
96 {
97 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
98 configData;
99 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
100 if (!venc_config_framerate(frame_rate))
101 return false;
102
103 break;
104 }
105 case QOMX_IndexConfigVideoIntraperiod:
106 {
107 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
108 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
109 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
110
111 if (set_nP_frames(intraperiod->nPFrames) == false ||
112 set_nB_frames(intraperiod->nBFrames) == false)
113 return false;
114
115 break;
116 }
117 case OMX_IndexConfigVideoIntraVOPRefresh:
118 {
119 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
120 configData;
121 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
122 if (!venc_config_intravoprefresh(intra_vop_refresh))
123 return false;
124
125 break;
126 }
127 case OMX_IndexConfigCommonMirror:
128 {
129 OMX_CONFIG_MIRRORTYPE *mirror = (OMX_CONFIG_MIRRORTYPE*) configData;
130 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigCommonMirror");
131
132 if (venc_set_mirror(mirror->eMirror) == false) {
133 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigCommonMirror failed");
134 return false;
135 }
136 break;
137 }
138 case OMX_IndexConfigCommonRotate:
139 {
140 OMX_CONFIG_ROTATIONTYPE *config_rotation =
141 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
142 OMX_U32 nFrameWidth;
143 if (!config_rotation) {
144 return false;
145 }
146
147 if (venc_handle->m_c2d_rotation) {
148 if (venc_prepare_c2d_rotation(config_rotation->nRotation) == false) {
149 DEBUG_PRINT_ERROR("ERROR: venc_prepare_c2d_rotation failed");
150 return false;
151 }
152 } else {
153 if (venc_set_vpe_rotation(config_rotation->nRotation) == false) {
154 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
155 return false;
156 }
157 }
158
159 break;
160 }
161 case OMX_IndexConfigVideoAVCIntraPeriod:
162 {
163 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
164 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
165
166 if (set_nP_frames(avc_iperiod->nPFrames) == false) {
167 DEBUG_PRINT_ERROR("ERROR: Setting intra period failed");
168 return false;
169 }
170 break;
171 }
172 case OMX_IndexConfigVideoVp8ReferenceFrame:
173 {
174 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
175 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
176 if (!venc_config_vp8refframe(vp8refframe))
177 return false;
178
179 break;
180 }
181 case OMX_QcomIndexConfigVideoLTRUse:
182 {
183 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
184 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
185 if (!venc_config_useLTR(pParam))
186 return false;
187
188 break;
189 }
190 case OMX_IndexParamVideoAndroidVp8Encoder:
191 {
192 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoAndroidVp8Encoder");
193 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8EncodeParams =
194 (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)configData;
195
196 if (vp8EncodeParams->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
197 int pFrames = vp8EncodeParams->nKeyFrameInterval - 1;
198 if (set_nP_frames(pFrames) == false) {
199 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
200 return false;
201 }
202
203 } else {
204 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAndroidVp8Encoder");
205 }
206 break;
207 }
208 case OMX_QcomIndexConfigVideoLTRMark:
209 {
210 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
211 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
212 if (!venc_config_markLTR(pParam))
213 return false;
214
215 break;
216 }
217 case OMX_IndexConfigAndroidVideoTemporalLayering:
218 {
219 OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *pParam =
220 (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *) configData;
221
222 // Update temporal_layers_config with input config
223 if (pParam->nPLayerCountActual < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS) {
224 temporal_layers_config.nPLayers = pParam->nPLayerCountActual;
225 } else {
226 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigAndroidVideoTemporalLayering failed");
227 return false;
228 }
229 temporal_layers_config.ePattern = pParam->ePattern;
230 temporal_layers_config.hier_mode = HIER_P;
231 temporal_layers_config.nBLayers = 0;
232 // Resetting to zero as we are sending all bitrate ratios to kernel
233 memset(&temporal_layers_config.nTemporalLayerBitrateRatio, 0x0, sizeof(OMX_U32)*OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS);
234 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers; ++i) {
235 temporal_layers_config.nTemporalLayerBitrateRatio[i] = pParam->nBitrateRatios[i];
236 }
237
238 if (OMX_ErrorNone != venc_set_hierp_layer()) {
239 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigAndroidVideoTemporalLayering failed in setting hierp layers");
240 return false;
241 }
242 if (OMX_ErrorNone != venc_set_bitrate_ratios()) {
243 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigAndroidVideoTemporalLayering failed in setting bitrate ratios");
244 return false;
245 }
246 break;
247 }
248 case OMX_QcomIndexConfigBaseLayerId:
249 {
250 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
251 (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
252 if (venc_set_baselayerid(pParam->nPID) == false) {
253 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
254 return false;
255 }
256 break;
257 }
258 case OMX_QcomIndexConfigQp:
259 {
260 OMX_QCOM_VIDEO_CONFIG_QP* pParam =
261 (OMX_QCOM_VIDEO_CONFIG_QP*) configData;
262 DEBUG_PRINT_LOW("Set_config: nQP %d", pParam->nQP);
263 if (!venc_config_qp(pParam))
264 return false;
265
266 break;
267 }
268 case OMX_IndexConfigPriority:
269 {
270 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
271 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
272 if (!venc_set_priority(priority->nU32)) {
273 DEBUG_PRINT_ERROR("Failed to set priority");
274 return false;
275 }
276 sess_priority.priority = priority->nU32;
277 break;
278 }
279 case OMX_IndexConfigOperatingRate:
280 {
281 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
282 DEBUG_PRINT_LOW("Set_config: operating rate %u", rate->nU32);
283 if (!venc_set_operatingrate(rate->nU32)) {
284 DEBUG_PRINT_ERROR("Failed to set operating rate");
285 return false;
286 }
287 break;
288 }
289 case OMX_IndexConfigAndroidIntraRefresh:
290 {
291 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh_period = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
292 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh_period->nRefreshPeriod);
293
294 if (intra_refresh_period->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
295 intra_refresh.framecount = intra_refresh_period->nRefreshPeriod;
296 intra_refresh.irmode = OMX_VIDEO_IntraRefreshRandom;
297 intra_refresh.mbcount = 0;
298 venc_set_intra_refresh();
299 } else {
300 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
301 }
302 break;
303 }
304 case OMX_QTIIndexConfigVideoBlurResolution:
305 {
306 OMX_QTI_VIDEO_CONFIG_BLURINFO *blur = (OMX_QTI_VIDEO_CONFIG_BLURINFO *)configData;
307 if (blur->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
308 DEBUG_PRINT_LOW("Set_config: blur resolution: %u", blur->nBlurInfo);
309 if(!venc_set_blur_resolution(blur)) {
310 DEBUG_PRINT_ERROR("Failed to set Blur Resolution");
311 return false;
312 }
313 } else {
314 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QTIIndexConfigVideoBlurResolution");
315 return false;
316 }
317 break;
318 }
319 case OMX_QTIIndexConfigDescribeColorAspects:
320 {
321 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
322
323 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
324 OMX_U32 full_range = 0;
325 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
326 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
327
328 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
329 case ColorAspects::PrimariesBT709_5:
330 color_space = MSM_VIDC_BT709_5;
331 break;
332 case ColorAspects::PrimariesBT470_6M:
333 color_space = MSM_VIDC_BT470_6_M;
334 break;
335 case ColorAspects::PrimariesBT601_6_625:
336 color_space = MSM_VIDC_BT601_6_625;
337 break;
338 case ColorAspects::PrimariesBT601_6_525:
339 color_space = MSM_VIDC_BT601_6_525;
340 break;
341 case ColorAspects::PrimariesGenericFilm:
342 color_space = MSM_VIDC_GENERIC_FILM;
343 break;
344 case ColorAspects::PrimariesBT2020:
345 color_space = MSM_VIDC_BT2020;
346 break;
347 default:
348 color_space = MSM_VIDC_BT601_6_625;
349 //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
350 break;
351 }
352 switch((ColorAspects::Range)params->sAspects.mRange) {
353 case ColorAspects::RangeFull:
354 full_range = 1;
355 break;
356 case ColorAspects::RangeLimited:
357 full_range = 0;
358 break;
359 default:
360 break;
361 }
362 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
363 case ColorAspects::TransferSMPTE170M:
364 transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
365 break;
366 case ColorAspects::TransferUnspecified:
367 transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
368 break;
369 case ColorAspects::TransferGamma22:
370 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
371 break;
372 case ColorAspects::TransferGamma28:
373 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
374 break;
375 case ColorAspects::TransferSMPTE240M:
376 transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
377 break;
378 case ColorAspects::TransferLinear:
379 transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
380 break;
381 case ColorAspects::TransferXvYCC:
382 transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
383 break;
384 case ColorAspects::TransferBT1361:
385 transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
386 break;
387 case ColorAspects::TransferSRGB:
388 transfer_chars = MSM_VIDC_TRANSFER_SRGB;
389 break;
390 case ColorAspects::TransferST2084:
391 transfer_chars = MSM_VIDC_TRANSFER_SMPTE_ST2084;
392 break;
393 case ColorAspects::TransferHLG:
394 transfer_chars = MSM_VIDC_TRANSFER_HLG;
395 break;
396 default:
397 //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
398 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
399 break;
400 }
401 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
402 case ColorAspects::MatrixUnspecified:
403 matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
404 break;
405 case ColorAspects::MatrixBT709_5:
406 matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
407 break;
408 case ColorAspects::MatrixBT470_6M:
409 matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
410 break;
411 case ColorAspects::MatrixBT601_6:
412 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
413 break;
414 case ColorAspects::MatrixSMPTE240M:
415 matrix_coeffs = MSM_VIDC_MATRIX_SMPTE_240M;
416 break;
417 case ColorAspects::MatrixBT2020:
418 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
419 break;
420 case ColorAspects::MatrixBT2020Constant:
421 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
422 break;
423 default:
424 //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
425 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
426 break;
427 }
428 if (!venc_set_colorspace(color_space, full_range,
429 transfer_chars, matrix_coeffs)) {
430
431 DEBUG_PRINT_ERROR("Failed to set operating rate");
432 return false;
433 }
434 break;
435 }
436 case OMX_QTIIndexConfigVideoRoiInfo:
437 {
438 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
439 DEBUG_PRINT_ERROR("Failed to set ROI QP info");
440 return false;
441 }
442 break;
443 }
444 case OMX_IndexConfigVideoNalSize:
445 {
446 if(!venc_set_nal_size((OMX_VIDEO_CONFIG_NALSIZE *)configData)) {
447 DEBUG_PRINT_LOW("Failed to set Nal size info");
448 return false;
449 }
450 break;
451 }
452 case OMX_QTIIndexConfigVideoRoiRectRegionInfo:
453 {
454 if(!venc_set_roi_region_qp_info((OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO *)configData)) {
455 DEBUG_PRINT_LOW("Failed to set ROI Region QP info");
456 return false;
457 }
458 break;
459 }
460 case OMX_QTIIndexConfigContentAdaptiveCoding:
461 {
462 if(!venc_set_bitrate_savings_mode(*(OMX_U32*) configData)) {
463 DEBUG_PRINT_LOW("Failed to set Bitrate Savings Mode");
464 return false;
465 }
466 break;
467 }
468 default:
469 DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
470 break;
471 }
472
473 return true;
474 }
475
venc_store_dynamic_config(OMX_INDEXTYPE config_type,OMX_PTR config)476 bool venc_dev::venc_store_dynamic_config(OMX_INDEXTYPE config_type, OMX_PTR config)
477 {
478 struct dynamicConfig newConfig;
479 memset(&newConfig, 0, sizeof(dynamicConfig));
480 newConfig.type = config_type;
481
482 switch ((int)config_type) {
483 case OMX_IndexConfigVideoFramerate:
484 memcpy(&newConfig.config_data.framerate, config, sizeof(OMX_CONFIG_FRAMERATETYPE));
485 break;
486 case OMX_IndexConfigVideoIntraVOPRefresh:
487 memcpy(&newConfig.config_data.intravoprefresh, config, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
488 break;
489 case OMX_IndexConfigVideoBitrate:
490 memcpy(&newConfig.config_data.bitrate, config, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
491 break;
492 case OMX_QcomIndexConfigVideoLTRUse:
493 memcpy(&newConfig.config_data.useltr, config, sizeof(OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE));
494 break;
495 case OMX_QcomIndexConfigVideoLTRMark:
496 memcpy(&newConfig.config_data.markltr, config, sizeof(OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE));
497 break;
498 case OMX_QcomIndexConfigQp:
499 memcpy(&newConfig.config_data.configqp, config, sizeof(OMX_QCOM_VIDEO_CONFIG_QP));
500 break;
501 case QOMX_IndexConfigVideoIntraperiod:
502 memcpy(&newConfig.config_data.intraperiod, config, sizeof(QOMX_VIDEO_INTRAPERIODTYPE));
503 break;
504 case OMX_IndexConfigVideoVp8ReferenceFrame:
505 memcpy(&newConfig.config_data.vp8refframe, config, sizeof(OMX_VIDEO_VP8REFERENCEFRAMETYPE));
506 break;
507 case OMX_IndexConfigCommonMirror:
508 memcpy(&newConfig.config_data.mirror, config, sizeof(OMX_CONFIG_MIRRORTYPE));
509 break;
510 default:
511 DEBUG_PRINT_INFO("Unsupported dynamic config.");
512 return false;
513 }
514
515 if(venc_handle->m_etb_count)
516 newConfig.timestamp = venc_handle->m_etb_timestamp + 1;
517 else
518 newConfig.timestamp = 0;
519
520 pthread_mutex_lock(&m_configlock);
521 DEBUG_PRINT_LOW("list add dynamic config with type %d timestamp %lld us", config_type, newConfig.timestamp);
522 m_configlist.push_back(newConfig);
523 pthread_mutex_unlock(&m_configlock);
524 return true;
525
526 }
527
venc_set_param(void * paramData,OMX_INDEXTYPE index)528 bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index)
529 {
530 DEBUG_PRINT_LOW("venc_set_param index 0x%x", index);
531 struct v4l2_format fmt;
532 struct v4l2_requestbuffers bufreq;
533 int ret;
534 bool isCBR;
535
536 switch ((int)index) {
537 case OMX_IndexParamPortDefinition:
538 {
539 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
540 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
541
542 if (portDefn->nPortIndex == PORT_INDEX_IN) {
543 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate)) {
544 return false;
545 }
546
547 unsigned long inputformat = venc_get_color_format(portDefn->format.video.eColorFormat);
548
549 unsigned long width = m_bDimensionsNeedFlip ? portDefn->format.video.nFrameHeight :
550 portDefn->format.video.nFrameWidth;
551 unsigned long height = m_bDimensionsNeedFlip ? portDefn->format.video.nFrameWidth :
552 portDefn->format.video.nFrameHeight;
553
554 if (m_sVenc_cfg.input_height != height || m_sVenc_cfg.input_width != width ||
555 m_sInput_buff_property.actualcount != portDefn->nBufferCountActual ||
556 m_sVenc_cfg.inputformat != inputformat) {
557
558 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition: port: %u, WxH %lux%lu --> %ux%u, count %lu --> %u, format %#lx --> %#lx",
559 portDefn->nPortIndex, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
560 portDefn->format.video.nFrameWidth, portDefn->format.video.nFrameHeight,
561 m_sInput_buff_property.actualcount, portDefn->nBufferCountActual,
562 m_sVenc_cfg.inputformat, inputformat);
563
564 if (portDefn->nBufferCountActual < m_sInput_buff_property.mincount) {
565 DEBUG_PRINT_LOW("Actual count %u is less than driver mincount %lu on port %u",
566 portDefn->nBufferCountActual, m_sInput_buff_property.mincount, portDefn->nPortIndex);
567 return false;
568 }
569
570 m_sVenc_cfg.input_height = height;
571 m_sVenc_cfg.input_width = width;
572 m_sVenc_cfg.inputformat = inputformat;
573 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
574
575 memset(&fmt, 0, sizeof(fmt));
576 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
577 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
578 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
579 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
580 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
581 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
582 DEBUG_PRINT_ERROR("set format failed, type %d, wxh %dx%d, pixelformat %#x, colorspace %#x",
583 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
584 fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.colorspace);
585 hw_overload = errno == EBUSY;
586 return false;
587 }
588 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
589
590 bufreq.memory = V4L2_MEMORY_USERPTR;
591 bufreq.count = portDefn->nBufferCountActual;
592 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
593 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
594 DEBUG_PRINT_ERROR("reqbufs failed, type %d, count %d", bufreq.type, bufreq.count);
595 return false;
596 }
597
598 if (num_input_planes > 1) {
599 input_extradata_info.count = m_sInput_buff_property.actualcount;
600 venc_handle->m_client_in_extradata_info.set_extradata_info(input_extradata_info.buffer_size, input_extradata_info.count);
601 }
602
603 if (!downscalar_enabled) {
604 m_sVenc_cfg.dvs_height = height;
605 m_sVenc_cfg.dvs_width = width;
606 }
607 memset(&fmt, 0, sizeof(fmt));
608 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
609 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
610 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
611 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
612
613 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
614 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
615 hw_overload = errno == EBUSY;
616 return false;
617 }
618 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
619
620 } else {
621 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition: parameters not changed on port %d",
622 portDefn->nPortIndex);
623 }
624 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
625
626 unsigned long codectype = venc_get_codectype(portDefn->format.video.eCompressionFormat);
627
628 unsigned long width = m_bDimensionsNeedFlip ? portDefn->format.video.nFrameHeight :
629 portDefn->format.video.nFrameWidth;
630 unsigned long height = m_bDimensionsNeedFlip ? portDefn->format.video.nFrameWidth :
631 portDefn->format.video.nFrameHeight;
632
633 //Don't worry about width/height if downscalar is enabled.
634 if (m_sVenc_cfg.dvs_height != height || m_sVenc_cfg.dvs_width != width ||
635 m_sOutput_buff_property.actualcount != portDefn->nBufferCountActual ||
636 m_sVenc_cfg.codectype != codectype) {
637
638 if (portDefn->nBufferCountActual < m_sOutput_buff_property.mincount) {
639 DEBUG_PRINT_LOW("Actual count %u is less than driver mincount %lu on port %u",
640 portDefn->nBufferCountActual, m_sOutput_buff_property.mincount, portDefn->nPortIndex);
641 return false;
642 }
643
644 //If downscalar is enabled. Correct width/height is populated no need to replace with port def width/height
645 if (!downscalar_enabled) {
646 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition: port: %u, WxH %lux%lu --> %ux%u, count %lu --> %u, format %#lx --> %#lx",
647 portDefn->nPortIndex, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
648 portDefn->format.video.nFrameWidth, portDefn->format.video.nFrameHeight,
649 m_sOutput_buff_property.actualcount, portDefn->nBufferCountActual,
650 m_sVenc_cfg.codectype, codectype);
651 m_sVenc_cfg.dvs_height = height;
652 m_sVenc_cfg.dvs_width = width;
653 }
654
655 m_sVenc_cfg.codectype = codectype;
656 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
657
658 memset(&fmt, 0, sizeof(fmt));
659 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
660 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
661 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
662 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
663 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
664 DEBUG_PRINT_ERROR("set format failed, type %d, wxh %dx%d, pixelformat %#x",
665 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
666 fmt.fmt.pix_mp.pixelformat);
667 hw_overload = errno == EBUSY;
668 return false;
669 }
670 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
671
672 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate)) {
673 return false;
674 }
675
676 bufreq.memory = V4L2_MEMORY_USERPTR;
677 bufreq.count = portDefn->nBufferCountActual;
678 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
679 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
680 DEBUG_PRINT_ERROR("reqbufs failed, type %d, count %d", bufreq.type, bufreq.count);
681 return false;
682 }
683
684 if (num_output_planes > 1) {
685 output_extradata_info.count = m_sOutput_buff_property.actualcount;
686 venc_handle->m_client_out_extradata_info.set_extradata_info(output_extradata_info.buffer_size, output_extradata_info.count);
687 }
688 } else {
689 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition: parameters not changed on port %d",
690 portDefn->nPortIndex);
691 }
692 } else {
693 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index (%d) for OMX_IndexParamPortDefinition", portDefn->nPortIndex);
694 }
695 }
696 break;
697 case OMX_IndexParamVideoPortFormat:
698 {
699 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
700 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
701 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
702
703 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
704 if (!venc_set_color_format(portFmt->eColorFormat)) {
705 return false;
706 }
707 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
708 if (!venc_set_encode_framerate(portFmt->xFramerate)) {
709 return false;
710 }
711 } else {
712 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
713 }
714 break;
715 }
716 case OMX_IndexParamVideoBitrate:
717 {
718 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
719 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
720 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
721
722 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
723 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
724 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
725 return false;
726 }
727
728 if (!venc_set_target_bitrate(pParam->nTargetBitrate)) {
729 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
730 return false;
731 }
732 } else {
733 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
734 }
735
736 break;
737 }
738 case OMX_IndexParamVideoAvc:
739 {
740 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
741 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
742 OMX_U32 bFrames = 0;
743
744 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
745 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
746 pParam->eProfile,pParam->eLevel);
747
748 if (!venc_set_profile (pParam->eProfile)) {
749 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
750 pParam->eProfile);
751 return false;
752 }
753
754 if (set_nP_frames(pParam->nPFrames) == false ||
755 (pParam->nBFrames && set_nB_frames(pParam->nBFrames) == false)) {
756 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
757 return false;
758 }
759 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
760 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
761 return false;
762 }
763 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
764 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
765 return false;
766 }
767
768 if (!venc_set_multislice_cfg(V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB, pParam->nSliceHeaderSpacing)) {
769 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
770 return false;
771 }
772 if (!venc_h264_transform_8x8(pParam->bDirect8x8Inference)) {
773 DEBUG_PRINT_ERROR("WARNING: Request for setting Transform8x8 failed");
774 return false;
775 }
776 } else {
777 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
778 }
779
780 //TBD, lot of other variables to be updated, yet to decide
781 break;
782 }
783 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
784 {
785 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
786 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
787
788 //TODO: Set VP8 level/profile currently based on driver change
789 if (!venc_set_profile (pParam->eProfile)) {
790 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
791 pParam->eProfile);
792 return false;
793 }
794 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
795 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
796 return false;
797 }
798 break;
799 }
800 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
801 {
802 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
803 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
804
805 if (!venc_set_profile (pParam->eProfile)) {
806 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
807 pParam->eProfile);
808 return false;
809 }
810 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
811 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
812
813 OMX_U32 fps = m_sVenc_cfg.fps_den ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
814 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
815 if (set_nP_frames(nPFrames) == false) {
816 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
817 return false;
818 }
819 break;
820 }
821 case (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid:
822 {
823 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoAndroidImageGrid. Ignore!");
824 break;
825 }
826 case OMX_IndexParamVideoIntraRefresh:
827 {
828 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
829 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh_param =
830 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
831
832 if (intra_refresh_param->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
833 intra_refresh.irmode = OMX_VIDEO_IntraRefreshCyclic;
834 intra_refresh.mbcount = intra_refresh_param->nCirMBs;
835 intra_refresh.framecount = 0;
836 venc_set_intra_refresh();
837 } else {
838 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
839 }
840
841 break;
842 }
843 case OMX_IndexParamVideoErrorCorrection:
844 {
845 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
846 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
847 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
848
849 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
850 if (venc_set_error_resilience(error_resilience) == false) {
851 DEBUG_PRINT_ERROR("ERROR: Setting Error Correction failed");
852 return false;
853 }
854 } else {
855 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
856 }
857
858 break;
859 }
860 case OMX_QcomIndexParamVideoSliceSpacing:
861 {
862 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoSliceSpacing");
863 QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE *slice_spacing =
864 (QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE*)paramData;
865
866 if (slice_spacing->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
867 if (!venc_set_multislice_cfg(slice_spacing->eSliceMode, slice_spacing->nSliceSize)) {
868 DEBUG_PRINT_ERROR("ERROR: Setting Slice Spacing failed");
869 return false;
870 }
871 } else {
872 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoSliceSpacing");
873 }
874
875 break;
876 }
877 case OMX_IndexParamVideoProfileLevelCurrent:
878 {
879 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
880 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
881 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
882
883 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
884 if (!venc_set_profile(profile_level->eProfile)) {
885 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile");
886 return false;
887 }
888 if (!venc_set_level(profile_level->eLevel)) {
889 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating level");
890 return false;
891 }
892 } else {
893 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
894 }
895
896 break;
897 }
898 case OMX_IndexParamVideoQuantization:
899 {
900 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
901 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
902 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
903 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
904 if (venc_set_qp(session_qp->nQpI,
905 session_qp->nQpP,
906 session_qp->nQpB,
907 ENABLE_I_QP | ENABLE_P_QP | ENABLE_B_QP) == false) {
908 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
909 return false;
910 }
911 } else {
912 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
913 }
914
915 break;
916 }
917 case QOMX_IndexParamVideoInitialQp:
918 {
919 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexParamVideoInitialQp");
920 QOMX_EXTNINDEX_VIDEO_INITIALQP *initial_qp =
921 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
922 if (initial_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
923 if (venc_set_qp(initial_qp->nQpI,
924 initial_qp->nQpP,
925 initial_qp->nQpB,
926 initial_qp->bEnableInitQp) == false) {
927 DEBUG_PRINT_ERROR("ERROR: Setting Initial QP failed");
928 return false;
929 }
930 } else {
931 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for QOMX_IndexParamVideoInitialQp");
932 }
933
934 break;
935 }
936 case OMX_QcomIndexParamVideoIPBQPRange:
937 {
938 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoIPBQPRange");
939 OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *session_qp_range =
940 (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *)paramData;
941 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
942 if ( venc_set_session_qp_range (session_qp_range) == false) {
943 DEBUG_PRINT_ERROR("ERROR: Setting QP range failed");
944 return false;
945 }
946 }
947
948 break;
949 }
950 case OMX_QcomIndexParamIndexExtraDataType:
951 {
952 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamIndexExtraDataType");
953 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
954
955 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Enc_ROI &&
956 m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
957 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
958 DEBUG_PRINT_ERROR("OMX_QTI_ExtraDataCategory_Enc_ROI is not supported for %lu codec", m_sVenc_cfg.codectype);
959 return false;
960 }
961
962 if (venc_set_extradata(pParam->nIndex, pParam->bEnabled) == false) {
963 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamIndexExtraDataType failed");
964 return false;
965 }
966
967 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Enc_ROI && pParam->bEnabled) {
968 m_roi_enabled = true;
969 struct v4l2_control control;
970 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE;
971 control.value = ROI_NONE;
972 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control)) {
973 DEBUG_PRINT_ERROR("ERROR: failed to query supported ROI type");
974 m_roi_type = ROI_NONE;
975 } else {
976 auto type = static_cast<roi_type>(control.value);
977 if (type != ROI_2BIT && type != ROI_2BYTE) {
978 DEBUG_PRINT_LOW("invalid ROI type : %u", m_roi_type);
979 m_roi_type = ROI_NONE;
980 } else {
981 m_roi_type = type;
982 DEBUG_PRINT_LOW("queried ROI type : %u", m_roi_type);
983 }
984 }
985 }
986
987 break;
988 }
989 case OMX_QcomIndexParamSequenceHeaderWithIDR:
990 {
991 PrependSPSPPSToIDRFramesParams * pParam =
992 (PrependSPSPPSToIDRFramesParams *)paramData;
993
994 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
995 if(venc_set_inband_video_header(pParam->bEnable) == false) {
996 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
997 return false;
998 }
999
1000 break;
1001 }
1002 case OMX_QcomIndexParamH264VUITimingInfo:
1003 {
1004 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1005 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1006 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1007 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1008 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1009 return false;
1010 } else {
1011 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1012 }
1013 break;
1014 }
1015 case OMX_QcomIndexParamVideoLTRCount:
1016 {
1017 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
1018 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1019 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1020 if (venc_set_ltrcount(pParam->nCount) == false) {
1021 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
1022 return false;
1023 }
1024 break;
1025 }
1026 case OMX_QcomIndexParamBatchSize:
1027 {
1028 OMX_PARAM_U32TYPE* pParam =
1029 (OMX_PARAM_U32TYPE*)paramData;
1030
1031 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1032 DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
1033 " on output port");
1034 return false;
1035 }
1036 break;
1037 }
1038 case OMX_QcomIndexParamVencAspectRatio:
1039 {
1040 if (!venc_set_aspectratio(paramData)) {
1041 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
1042 return false;
1043 }
1044 break;
1045 }
1046 case OMX_QTIIndexParamLowLatencyMode:
1047 {
1048 QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE *pParam =
1049 (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
1050
1051 if (!venc_set_lowlatency_mode(pParam->bEnableLowLatencyMode)) {
1052 DEBUG_PRINT_ERROR("Setting low latency mode failed");
1053 return false;
1054 }
1055 break;
1056 }
1057 case OMX_IndexParamAndroidVideoTemporalLayering:
1058 {
1059 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE hierData;
1060 memcpy(&hierData, paramData, sizeof(hierData));
1061
1062 // Update temporal_layers_config with input param
1063 if (hierData.nPLayerCountActual < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS) {
1064 temporal_layers_config.nPLayers = hierData.nPLayerCountActual;
1065 } else {
1066 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed");
1067 return false;
1068 }
1069 temporal_layers_config.ePattern = hierData.ePattern;
1070 temporal_layers_config.hier_mode = HIER_P;
1071 temporal_layers_config.nMaxLayers = hierData.nLayerCountMax;
1072 temporal_layers_config.nMaxBLayers = hierData.nBLayerCountMax;
1073 temporal_layers_config.nBLayers = hierData.nBLayerCountActual;
1074 // Resetting to zero as we are sending all bitrate ratios to kernel
1075 memset(&temporal_layers_config.nTemporalLayerBitrateRatio, 0x0, sizeof(OMX_U32)*OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS);
1076 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers; ++i) {
1077 temporal_layers_config.nTemporalLayerBitrateRatio[i] = hierData.nBitrateRatios[i];
1078 }
1079
1080 if (OMX_ErrorNone != venc_set_max_hierp_layer()) {
1081 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting max hierp layers");
1082 return false;
1083 }
1084 if (OMX_ErrorNone != venc_set_hierp_layer()) {
1085 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting hierp layers");
1086 return false;
1087 }
1088 if (OMX_ErrorNone != venc_set_bitrate_ratios()) {
1089 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting bitrate ratios");
1090 return false;
1091 }
1092 break;
1093 }
1094 case OMX_QTIIndexParamEnableAVTimerTimestamps:
1095 {
1096 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1097 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
1098 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
1099 break;
1100 }
1101 case OMX_QcomIndexParamVideoDownScalar:
1102 {
1103 QOMX_INDEXDOWNSCALAR *pParam = (QOMX_INDEXDOWNSCALAR *)paramData;
1104 downscalar_enabled = pParam->bEnable;
1105
1106 DEBUG_PRINT_INFO("Downscalar settings: Enabled : %d Width : %u Height %u",
1107 pParam->bEnable, pParam->nOutputWidth, pParam->nOutputHeight);
1108 if (downscalar_enabled) {
1109 m_sVenc_cfg.dvs_width = pParam->nOutputWidth;
1110 m_sVenc_cfg.dvs_height = pParam->nOutputHeight;
1111
1112 memset(&fmt, 0, sizeof(fmt));
1113 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1114 fmt.fmt.pix_mp.width = pParam->nOutputWidth;
1115 fmt.fmt.pix_mp.height = pParam->nOutputHeight;
1116 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1117 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1118 DEBUG_PRINT_ERROR("Failed to set format on capture port");
1119 return false;
1120 }
1121 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1122 }
1123 break;
1124 }
1125 case OMX_QTIIndexParamColorSpaceConversion:
1126 {
1127 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1128 csc_enable = pParam->bEnable;
1129 DEBUG_PRINT_INFO("CSC settings: Enabled : %d ", pParam->bEnable);
1130 break;
1131 }
1132 case OMX_QTIIndexParamEnableLinearColorFormat:
1133 {
1134 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1135 mUseLinearColorFormat = pParam->bEnable ? REQUEST_LINEAR_COLOR_ALL : 0;
1136 DEBUG_PRINT_INFO("Linear Color Format Enabled : %d ", pParam->bEnable);
1137 break;
1138 }
1139 case OMX_QTIIndexParamNativeRecorder:
1140 {
1141 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1142 if (!set_native_recoder(pParam->bEnable)) {
1143 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamNativeRecorder failed");
1144 return false;
1145 }
1146 DEBUG_PRINT_INFO("Native recorder encode session %d", pParam->bEnable);
1147 break;
1148 }
1149 case OMX_QTIIndexParamVbvDelay:
1150 {
1151 OMX_EXTNINDEX_VIDEO_VBV_DELAY *pParam =
1152 (OMX_EXTNINDEX_VIDEO_VBV_DELAY*)paramData;
1153 if (!venc_set_vbv_delay(pParam->nVbvDelay)) {
1154 DEBUG_PRINT_ERROR("Setting OMX_QTIIndexParamVbvDelay failed");
1155 return false;
1156 }
1157 break;
1158 }
1159 default:
1160 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1161 index);
1162 break;
1163 }
1164
1165 return true;
1166 }
1167
venc_set_inband_video_header(OMX_BOOL enable)1168 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
1169 {
1170 struct v4l2_control control;
1171
1172 control.id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR;
1173 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1174 if(enable) {
1175 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1176 }
1177
1178 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
1179 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
1180 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
1181 return false;
1182 }
1183 return true;
1184 }
1185
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)1186 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
1187 {
1188 struct v4l2_control control;
1189
1190 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
1191
1192 if (enable == OMX_FALSE) {
1193 /* No easy way to turn off extradata to the driver
1194 * at the moment */
1195 return false;
1196 }
1197
1198 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
1199 switch (extra_data) {
1200 case OMX_QTI_ExtraDataCategory_Advanced:
1201 control.value = EXTRADATA_ADVANCED;
1202 break;
1203 case OMX_QTI_ExtraDataCategory_Enc_ROI:
1204 control.value = EXTRADATA_ENC_INPUT_ROI;
1205 break;
1206 default:
1207 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
1208 return false;
1209 }
1210
1211 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1212 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
1213 (unsigned int)extra_data, errno);
1214 return false;
1215 }
1216
1217 return true;
1218 }
1219
venc_set_session_qp_range(OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE * qp_range)1220 bool venc_dev::venc_set_session_qp_range(OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE* qp_range)
1221 {
1222 int rc;
1223 struct v4l2_control control[2];
1224
1225 control[0].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
1226 control[0].value = qp_range->minIQP | (qp_range->minPQP << 8) | (qp_range->minBQP << 16);
1227
1228 control[1].id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
1229 control[1].value = qp_range->maxIQP | (qp_range->maxPQP << 8) | (qp_range->maxBQP << 16);
1230
1231 for(int i=0; i<2; i++) {
1232 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control[i])) {
1233 DEBUG_PRINT_ERROR("Failed to set QP %s range", i==0?"MIN":"MAX");
1234 return false;
1235 }
1236 }
1237
1238 session_ipb_qp_values.min_qp_packed = control[0].value;
1239 session_ipb_qp_values.max_qp_packed = control[1].value;
1240
1241 return true;
1242 }
1243
venc_set_profile(OMX_U32 eProfile)1244 bool venc_dev::venc_set_profile(OMX_U32 eProfile)
1245 {
1246 int rc;
1247 struct v4l2_control control;
1248
1249 DEBUG_PRINT_LOW("venc_set_profile:: eProfile = %u",
1250 (unsigned int)eProfile);
1251
1252 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1253 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
1254 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1255 control.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
1256 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1257 control.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
1258 } else {
1259 DEBUG_PRINT_ERROR("Wrong CODEC");
1260 return false;
1261 }
1262
1263 if (!profile_level_converter::convert_omx_profile_to_v4l2(m_sVenc_cfg.codectype, eProfile, &control.value)) {
1264 DEBUG_PRINT_ERROR("Cannot find v4l2 profile for OMX profile : %d Codec : %lu ",
1265 eProfile, m_sVenc_cfg.codectype);
1266 return false;
1267 }
1268
1269 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1270 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1271
1272 if (rc) {
1273 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1274 return false;
1275 }
1276 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1277
1278 codec_profile.profile = control.value;
1279
1280 if (venc_set_extradata_hdr10metadata(eProfile) == false) {
1281 DEBUG_PRINT_ERROR("Failed to set extradata HDR10PLUS_METADATA");
1282 return false;
1283 }
1284
1285 return true;
1286 }
1287
venc_set_level(OMX_U32 eLevel)1288 bool venc_dev::venc_set_level(OMX_U32 eLevel)
1289 {
1290 int rc;
1291 struct v4l2_control control;
1292 unsigned int tier = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH;
1293 OMX_U32 omx_profile_level = eLevel;
1294
1295 DEBUG_PRINT_LOW("venc_set_level:: eLevel = %u",
1296 (unsigned int)eLevel);
1297
1298 if (!eLevel) {
1299 DEBUG_PRINT_ERROR(" Unknown OMX level : %u" ,
1300 (unsigned int)eLevel );
1301 return true;
1302 }
1303 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1304 if(!profile_level_converter::find_tier(m_sVenc_cfg.codectype, eLevel, &tier)) {
1305 DEBUG_PRINT_ERROR("Failed to find HEVC v4l2 level tier for OMX level : %d", eLevel);
1306 return true;
1307 }
1308 /* HEVC high tier profile levels are mapped to same V4L2 profile levels as main tier profile levels */
1309 if (tier == V4L2_MPEG_VIDEO_HEVC_TIER_HIGH)
1310 omx_profile_level = eLevel >> 1;
1311 }
1312 if (!profile_level_converter::convert_omx_level_to_v4l2(m_sVenc_cfg.codectype, omx_profile_level, &control.value)) {
1313 DEBUG_PRINT_ERROR("Failed to find v4l2 level for OMX level : %d" \
1314 " Codec : %lu", eLevel, m_sVenc_cfg.codectype);
1315 return true;
1316 }
1317
1318 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1319 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
1320 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1321 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
1322 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1323 control.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
1324 profile_level.tier = tier;
1325 }
1326 else {
1327 DEBUG_PRINT_ERROR("Wrong CODEC");
1328 return false;
1329 }
1330
1331 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d",
1332 control.id, control.value);
1333 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1334 if (rc) {
1335 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d",
1336 control.id, control.value);
1337 return false;
1338 }
1339 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d",
1340 control.id, control.value);
1341
1342 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1343 struct v4l2_control control_tier = {
1344 .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER,
1345 .value = (signed int)tier
1346 };
1347 DEBUG_PRINT_LOW("Calling IOCTL set tier control for HEVC, id %#x, value %d",
1348 control_tier.id, control_tier.value);
1349
1350 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_tier);
1351 if (rc) {
1352 DEBUG_PRINT_ERROR("Failed to set tier control for HEVC, id %#x, value %d",
1353 control_tier.id, control_tier.value);
1354 } else {
1355 profile_level.tier = control_tier.value;
1356 }
1357 }
1358 profile_level.level = control.value;
1359 return true;
1360 }
1361
venc_set_grid_enable()1362 bool venc_dev::venc_set_grid_enable()
1363 {
1364 int rc;
1365 struct v4l2_control control;
1366
1367 DEBUG_PRINT_LOW("venc_set_grid_enable");
1368 control.id = V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE;
1369 control.value = 1; // TODO: DO we need to get this value from input argument?
1370 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1371
1372 if (rc) {
1373 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1374 return false;
1375 }
1376
1377 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1378 mIsGridset = true;
1379 return true;
1380 }
1381
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)1382 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
1383 {
1384 int rc = 0;
1385 struct v4l2_control control;
1386
1387 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
1388
1389 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
1390 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
1391 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
1392 } else if (!enable) {
1393 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
1394 } else {
1395 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
1396 return false;
1397 }
1398
1399 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
1400
1401 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1402 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1403
1404 if (rc) {
1405 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1406 return false;
1407 }
1408
1409 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1410 entropy.longentropysel = control.value;
1411
1412 return true;
1413 }
1414
venc_set_multislice_cfg(OMX_U32 nSlicemode,OMX_U32 nSlicesize)1415 bool venc_dev::venc_set_multislice_cfg(OMX_U32 nSlicemode, OMX_U32 nSlicesize)
1416 {
1417 int rc;
1418 int slice_id = 0;
1419 struct v4l2_control control;
1420 bool status = true;
1421
1422 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 || nSlicesize == 0) {
1423 nSlicemode = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
1424 nSlicesize = 0;
1425 }
1426
1427 if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
1428 if (!venc_validate_range(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, nSlicesize)) {
1429 DEBUG_PRINT_ERROR("Invalid settings, hardware doesn't support %u as slicesize", nSlicesize);
1430 return false;
1431 }
1432 slice_id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
1433
1434 } else if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
1435 if (!venc_validate_range(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, nSlicesize)) {
1436 DEBUG_PRINT_ERROR("Invalid settings, hardware doesn't support %u as slicesize", nSlicesize);
1437 return false;
1438 }
1439 slice_id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
1440
1441 } else if (nSlicesize) {
1442 DEBUG_PRINT_ERROR("Invalid settings, unexpected slicemode = %u and slice size = %u", nSlicemode, nSlicesize);
1443 return false;
1444 }
1445
1446 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
1447 control.value = nSlicemode;
1448
1449 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1450 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1451
1452 if (rc) {
1453 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1454 return false;
1455 }
1456
1457 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1458
1459 if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
1460 return status;
1461 }
1462
1463 control.id = slice_id;
1464 control.value = nSlicesize;
1465
1466 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
1467 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1468
1469 if (rc) {
1470 DEBUG_PRINT_ERROR("Failed to set control");
1471 return false;
1472 }
1473
1474 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1475
1476 multislice.mslice_mode = nSlicemode;
1477 multislice.mslice_size = nSlicesize;
1478
1479 return status;
1480 }
1481
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)1482 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
1483 {
1484 bool status = true;
1485 struct venc_headerextension hec_cfg;
1486 struct venc_multiclicecfg multislice_cfg;
1487 int rc;
1488 OMX_U32 resynchMarkerSpacingBytes = 0;
1489 struct v4l2_control control;
1490
1491 memset(&control, 0, sizeof(control));
1492
1493 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
1494 if (error_resilience->bEnableHEC) {
1495 hec_cfg.header_extension = 1;
1496 } else {
1497 hec_cfg.header_extension = 0;
1498 }
1499
1500 hec.header_extension = error_resilience->bEnableHEC;
1501 }
1502
1503 if (error_resilience->bEnableRVLC) {
1504 DEBUG_PRINT_ERROR("RVLC is not Supported");
1505 return false;
1506 }
1507
1508 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
1509 (error_resilience->bEnableDataPartitioning)) {
1510 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
1511 return false;
1512 }
1513
1514 if (error_resilience->nResynchMarkerSpacing) {
1515 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
1516 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
1517 }
1518
1519 status = venc_set_multislice_cfg(V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, resynchMarkerSpacingBytes);
1520
1521 return status;
1522 }
1523
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)1524 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
1525 {
1526 int rc;
1527 struct v4l2_control control;
1528 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
1529 control.value=0;
1530
1531 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
1532 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
1533 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
1534 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
1535 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
1536 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
1537 }
1538
1539 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1540 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1541
1542 if (rc) {
1543 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1544 return false;
1545 }
1546
1547 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1548
1549 dbkfilter.db_mode=control.value;
1550
1551 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
1552 control.value=0;
1553
1554 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1555 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1556
1557 if (rc) {
1558 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1559 return false;
1560 }
1561
1562 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1563 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
1564 control.value=0;
1565 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1566 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1567
1568 if (rc) {
1569 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1570 return false;
1571 }
1572
1573 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1574
1575
1576 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
1577 return true;
1578 }
1579
venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat)1580 unsigned long venc_dev::venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat)
1581 {
1582 unsigned long codectype = V4L2_PIX_FMT_H264;
1583
1584 switch ((int)eCompressionFormat) {
1585 case OMX_VIDEO_CodingAVC:
1586 codectype = V4L2_PIX_FMT_H264;
1587 break;
1588 case OMX_VIDEO_CodingVP8:
1589 codectype = V4L2_PIX_FMT_VP8;
1590 break;
1591 case OMX_VIDEO_CodingVP9:
1592 codectype = V4L2_PIX_FMT_VP9;
1593 break;
1594 case OMX_VIDEO_CodingHEVC:
1595 case OMX_VIDEO_CodingImageHEIC:
1596 codectype = V4L2_PIX_FMT_HEVC;
1597 break;
1598 default:
1599 DEBUG_PRINT_ERROR("Unsupported eCompressionFormat %#x", eCompressionFormat);
1600 codectype = V4L2_PIX_FMT_H264;
1601 break;
1602 }
1603
1604 return codectype;
1605 }
1606
venc_set_bitrate_savings_mode(OMX_U32 bitrateSavingEnable)1607 bool venc_dev::venc_set_bitrate_savings_mode(OMX_U32 bitrateSavingEnable)
1608 {
1609 struct v4l2_control control;
1610 int rc = 0;
1611
1612 DEBUG_PRINT_LOW("Set bitrate savings %d", bitrateSavingEnable);
1613 control.id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS;
1614 control.value = bitrateSavingEnable;
1615 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1616 if (rc) {
1617 DEBUG_PRINT_HIGH("Non-Fatal: Request to set bitrate savings failed");
1618 }
1619 mBitrateSavingsEnable = bitrateSavingEnable;
1620
1621 return true;
1622 }
1623
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)1624 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
1625 {
1626 bool status = true;
1627 struct v4l2_control control;
1628 int rc = 0;
1629
1630 control.id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
1631 control.value = !!((OMX_U32)eControlRate ^ (OMX_U32)OMX_Video_ControlRateDisable);
1632 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1633 if (rc) {
1634 DEBUG_PRINT_ERROR("Failed to set RC_ENABLE");
1635 return false;
1636 }
1637
1638 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
1639 int temp = eControlRate;
1640 switch ((OMX_U32)eControlRate) {
1641 case OMX_Video_ControlRateDisable:
1642 control.value = -1;
1643 break;
1644 case OMX_Video_ControlRateVariableSkipFrames:
1645 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
1646 break;
1647 case OMX_Video_ControlRateVariable:
1648 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
1649 break;
1650 case OMX_Video_ControlRateConstantSkipFrames:
1651 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR;
1652 break;
1653 case OMX_Video_ControlRateConstant:
1654 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
1655 break;
1656 case QOMX_Video_ControlRateMaxBitrate:
1657 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR;
1658 break;
1659 case QOMX_Video_ControlRateMaxBitrateSkipFrames:
1660 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR;
1661 break;
1662 case OMX_Video_ControlRateConstantQuality:
1663 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CQ;
1664 break;
1665 default:
1666 status = false;
1667 break;
1668 }
1669
1670 if (status && control.value != -1) {
1671
1672 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1673 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1674
1675 if (rc) {
1676 DEBUG_PRINT_ERROR("Failed to set control");
1677 return false;
1678 }
1679
1680 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1681
1682 rate_ctrl.rcmode = control.value;
1683 }
1684
1685 venc_set_bitrate_savings_mode(mBitrateSavingsEnable);
1686
1687 return status;
1688 }
1689
venc_set_aspectratio(void * nSar)1690 bool venc_dev::venc_set_aspectratio(void *nSar)
1691 {
1692 int rc;
1693 struct v4l2_control control;
1694 struct v4l2_ext_control ctrl[2];
1695 struct v4l2_ext_controls controls;
1696 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
1697
1698 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
1699
1700 ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
1701 ctrl[0].value = sar->nSARWidth;
1702 ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
1703 ctrl[1].value = sar->nSARHeight;
1704
1705 controls.count = 2;
1706 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
1707 controls.controls = ctrl;
1708
1709 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
1710 controls.controls[0].id, controls.controls[0].value,
1711 controls.controls[1].id, controls.controls[1].value);
1712
1713 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
1714 if (rc) {
1715 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
1716 return false;
1717 }
1718
1719 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
1720 controls.controls[0].id, controls.controls[0].value,
1721 controls.controls[1].id, controls.controls[1].value);
1722 return true;
1723 }
1724
venc_set_lowlatency_mode(OMX_BOOL enable)1725 bool venc_dev::venc_set_lowlatency_mode(OMX_BOOL enable)
1726 {
1727 int rc = 0;
1728 struct v4l2_control control;
1729
1730 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
1731 if (enable)
1732 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1733 else
1734 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1735
1736 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
1737 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1738 if (rc) {
1739 DEBUG_PRINT_ERROR("Failed to set lowlatency control");
1740 return false;
1741 }
1742 low_latency_mode = enable;
1743 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
1744
1745 return true;
1746 }
1747
venc_set_vui_timing_info(OMX_BOOL enable)1748 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
1749 {
1750 struct v4l2_control control;
1751 int rc = 0;
1752 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO;
1753
1754 if (enable)
1755 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1756 else
1757 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1758
1759 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
1760 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1761 if (rc) {
1762 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
1763 return false;
1764 }
1765 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
1766 return true;
1767 }
1768
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)1769 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
1770 {
1771 struct v4l2_control control;
1772 int rc = 0;
1773 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
1774 control.value = nPeakBitrate;
1775
1776 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
1777
1778 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1779 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1780
1781 if (rc) {
1782 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
1783 return false;
1784 }
1785
1786 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1787
1788 return true;
1789 }
1790
venc_set_vpx_error_resilience(OMX_BOOL enable)1791 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
1792 {
1793 struct v4l2_control control;
1794 int rc = 0;
1795 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
1796
1797 if (enable)
1798 control.value = 1;
1799 else
1800 control.value = 0;
1801
1802 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
1803
1804 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1805
1806 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1807 if (rc) {
1808 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
1809 return false;
1810 }
1811 vpx_err_resilience.enable = 1;
1812 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1813 return true;
1814 }
1815
venc_set_vbv_delay(OMX_U32 nVbvDelay)1816 bool venc_dev::venc_set_vbv_delay(OMX_U32 nVbvDelay)
1817 {
1818 int rc = 0;
1819 struct v4l2_control control;
1820
1821 control.id = V4L2_CID_MPEG_VIDEO_VBV_DELAY;
1822 control.value = nVbvDelay;
1823
1824 DEBUG_PRINT_LOW("venc_set_vbv_delay: vbvdelay = %u", (unsigned int)control.value);
1825
1826 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1827 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1828
1829 if (rc) {
1830 DEBUG_PRINT_ERROR("Failed to set vbv delay");
1831 return false;
1832 }
1833
1834 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1835 return true;
1836 }
1837