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