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
771 if (set_nP_frames(pParam->nPFrames) == false ||
772 (pParam->nBFrames && set_nB_frames(pParam->nBFrames) == false)) {
773 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
774 return false;
775 }
776 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
777 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
778 return false;
779 }
780 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
781 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
782 return false;
783 }
784
785 if (!venc_set_multislice_cfg(V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB, pParam->nSliceHeaderSpacing)) {
786 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
787 return false;
788 }
789 if (!venc_h264_transform_8x8(pParam->bDirect8x8Inference)) {
790 DEBUG_PRINT_ERROR("WARNING: Request for setting Transform8x8 failed");
791 return false;
792 }
793 } else {
794 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
795 }
796
797 //TBD, lot of other variables to be updated, yet to decide
798 break;
799 }
800 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
801 {
802 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
803 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
804
805 //TODO: Set VP8 level/profile currently based on driver change
806 if (!venc_set_profile (pParam->eProfile)) {
807 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
808 pParam->eProfile);
809 return false;
810 }
811 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
812 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
813 return false;
814 }
815 break;
816 }
817 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
818 {
819 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
820 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
821
822 if (!venc_set_profile (pParam->eProfile)) {
823 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
824 pParam->eProfile);
825 return false;
826 }
827 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
828 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
829
830 OMX_U32 fps = m_sVenc_cfg.fps_den ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
831 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
832 if (set_nP_frames(nPFrames) == false) {
833 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
834 return false;
835 }
836 break;
837 }
838 case (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid:
839 {
840 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoAndroidImageGrid. Ignore!");
841 break;
842 }
843 case OMX_IndexParamVideoIntraRefresh:
844 {
845 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
846 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh_param =
847 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
848
849 if (intra_refresh_param->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
850 intra_refresh.irmode = OMX_VIDEO_IntraRefreshCyclic;
851 intra_refresh.mbcount = intra_refresh_param->nCirMBs;
852 intra_refresh.framecount = 0;
853 venc_set_intra_refresh();
854 } else {
855 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
856 }
857
858 break;
859 }
860 case OMX_IndexParamVideoErrorCorrection:
861 {
862 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
863 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
864 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
865
866 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
867 if (venc_set_error_resilience(error_resilience) == false) {
868 DEBUG_PRINT_ERROR("ERROR: Setting Error Correction failed");
869 return false;
870 }
871 } else {
872 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
873 }
874
875 break;
876 }
877 case OMX_QcomIndexParamVideoSliceSpacing:
878 {
879 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoSliceSpacing");
880 QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE *slice_spacing =
881 (QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE*)paramData;
882
883 if (slice_spacing->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
884 if (!venc_set_multislice_cfg(slice_spacing->eSliceMode, slice_spacing->nSliceSize)) {
885 DEBUG_PRINT_ERROR("ERROR: Setting Slice Spacing failed");
886 return false;
887 }
888 } else {
889 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoSliceSpacing");
890 }
891
892 break;
893 }
894 case OMX_IndexParamVideoProfileLevelCurrent:
895 {
896 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
897 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
898 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
899
900 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
901 if (!venc_set_profile(profile_level->eProfile)) {
902 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile");
903 return false;
904 }
905 if (!venc_set_level(profile_level->eLevel)) {
906 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating level");
907 return false;
908 }
909 } else {
910 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
911 }
912
913 break;
914 }
915 case OMX_IndexParamVideoQuantization:
916 {
917 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
918 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
919 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
920 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
921 if (venc_set_qp(session_qp->nQpI,
922 session_qp->nQpP,
923 session_qp->nQpB,
924 ENABLE_I_QP | ENABLE_P_QP | ENABLE_B_QP) == false) {
925 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
926 return false;
927 }
928 } else {
929 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
930 }
931
932 break;
933 }
934 case QOMX_IndexParamVideoInitialQp:
935 {
936 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexParamVideoInitialQp");
937 QOMX_EXTNINDEX_VIDEO_INITIALQP *initial_qp =
938 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
939 if (initial_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
940 if (venc_set_qp(initial_qp->nQpI,
941 initial_qp->nQpP,
942 initial_qp->nQpB,
943 initial_qp->bEnableInitQp) == false) {
944 DEBUG_PRINT_ERROR("ERROR: Setting Initial QP failed");
945 return false;
946 }
947 } else {
948 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for QOMX_IndexParamVideoInitialQp");
949 }
950
951 break;
952 }
953 case OMX_QcomIndexParamVideoIPBQPRange:
954 {
955 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoIPBQPRange");
956 OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *session_qp_range =
957 (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *)paramData;
958 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
959 if ( venc_set_session_qp_range (session_qp_range) == false) {
960 DEBUG_PRINT_ERROR("ERROR: Setting QP range failed");
961 return false;
962 }
963 }
964
965 break;
966 }
967 case OMX_QcomIndexParamIndexExtraDataType:
968 {
969 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamIndexExtraDataType");
970 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
971
972 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Enc_ROI &&
973 m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
974 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
975 DEBUG_PRINT_ERROR("OMX_QTI_ExtraDataCategory_Enc_ROI is not supported for %lu codec", m_sVenc_cfg.codectype);
976 return false;
977 }
978
979 if (venc_set_extradata(pParam->nIndex, pParam->bEnabled) == false) {
980 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamIndexExtraDataType failed");
981 return false;
982 }
983
984 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Enc_ROI && pParam->bEnabled) {
985 m_roi_enabled = true;
986 struct v4l2_control control;
987 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE;
988 control.value = ROI_NONE;
989 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control)) {
990 DEBUG_PRINT_ERROR("ERROR: failed to query supported ROI type");
991 m_roi_type = ROI_NONE;
992 } else {
993 auto type = static_cast<roi_type>(control.value);
994 if (type != ROI_2BIT && type != ROI_2BYTE) {
995 DEBUG_PRINT_LOW("invalid ROI type : %u", m_roi_type);
996 m_roi_type = ROI_NONE;
997 } else {
998 m_roi_type = type;
999 DEBUG_PRINT_LOW("queried ROI type : %u", m_roi_type);
1000 }
1001 }
1002 }
1003
1004 break;
1005 }
1006 case OMX_QcomIndexParamSequenceHeaderWithIDR:
1007 {
1008 PrependSPSPPSToIDRFramesParams * pParam =
1009 (PrependSPSPPSToIDRFramesParams *)paramData;
1010
1011 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
1012 if(venc_set_inband_video_header(pParam->bEnable) == false) {
1013 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
1014 return false;
1015 }
1016
1017 break;
1018 }
1019 case OMX_QcomIndexParamH264VUITimingInfo:
1020 {
1021 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1022 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1023 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1024 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1025 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1026 return false;
1027 } else {
1028 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1029 }
1030 break;
1031 }
1032 case OMX_QcomIndexParamVideoLTRCount:
1033 {
1034 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
1035 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1036 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1037 if (venc_set_ltrcount(pParam->nCount) == false) {
1038 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
1039 return false;
1040 }
1041 break;
1042 }
1043 case OMX_QcomIndexParamBatchSize:
1044 {
1045 OMX_PARAM_U32TYPE* pParam =
1046 (OMX_PARAM_U32TYPE*)paramData;
1047
1048 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1049 DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
1050 " on output port");
1051 return false;
1052 }
1053 break;
1054 }
1055 case OMX_QcomIndexParamVencAspectRatio:
1056 {
1057 if (!venc_set_aspectratio(paramData)) {
1058 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
1059 return false;
1060 }
1061 break;
1062 }
1063 case OMX_QTIIndexParamLowLatencyMode:
1064 {
1065 QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE *pParam =
1066 (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
1067
1068 if (!venc_set_lowlatency_mode(pParam->bEnableLowLatencyMode)) {
1069 DEBUG_PRINT_ERROR("Setting low latency mode failed");
1070 return false;
1071 }
1072 break;
1073 }
1074 case OMX_IndexParamAndroidVideoTemporalLayering:
1075 {
1076 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE hierData;
1077 memcpy(&hierData, paramData, sizeof(hierData));
1078
1079 // Update temporal_layers_config with input param
1080 if (hierData.nPLayerCountActual < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS) {
1081 temporal_layers_config.nPLayers = hierData.nPLayerCountActual;
1082 } else {
1083 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed");
1084 return false;
1085 }
1086 temporal_layers_config.ePattern = hierData.ePattern;
1087 temporal_layers_config.hier_mode = HIER_P;
1088 temporal_layers_config.nMaxLayers = hierData.nLayerCountMax;
1089 temporal_layers_config.nMaxBLayers = hierData.nBLayerCountMax;
1090 temporal_layers_config.nBLayers = hierData.nBLayerCountActual;
1091 // Resetting to zero as we are sending all bitrate ratios to kernel
1092 memset(&temporal_layers_config.nTemporalLayerBitrateRatio, 0x0, sizeof(OMX_U32)*OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS);
1093 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers; ++i) {
1094 temporal_layers_config.nTemporalLayerBitrateRatio[i] = hierData.nBitrateRatios[i];
1095 }
1096
1097 if (OMX_ErrorNone != venc_set_max_hierp_layer()) {
1098 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting max hierp layers");
1099 return false;
1100 }
1101 if (OMX_ErrorNone != venc_set_hierp_layer()) {
1102 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting hierp layers");
1103 return false;
1104 }
1105 if (OMX_ErrorNone != venc_set_bitrate_ratios()) {
1106 DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexParamAndroidVideoTemporalLayering failed in setting bitrate ratios");
1107 return false;
1108 }
1109 break;
1110 }
1111 case OMX_QTIIndexParamEnableAVTimerTimestamps:
1112 {
1113 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1114 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
1115 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
1116 break;
1117 }
1118 case OMX_QcomIndexParamVideoDownScalar:
1119 {
1120 QOMX_INDEXDOWNSCALAR *pParam = (QOMX_INDEXDOWNSCALAR *)paramData;
1121 downscalar_enabled = pParam->bEnable;
1122
1123 DEBUG_PRINT_INFO("Downscalar settings: Enabled : %d Width : %u Height %u",
1124 pParam->bEnable, pParam->nOutputWidth, pParam->nOutputHeight);
1125 if (downscalar_enabled) {
1126 m_sVenc_cfg.dvs_width = pParam->nOutputWidth;
1127 m_sVenc_cfg.dvs_height = pParam->nOutputHeight;
1128
1129 memset(&fmt, 0, sizeof(fmt));
1130 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1131 fmt.fmt.pix_mp.width = pParam->nOutputWidth;
1132 fmt.fmt.pix_mp.height = pParam->nOutputHeight;
1133 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1134 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1135 DEBUG_PRINT_ERROR("Failed to set format on capture port");
1136 return false;
1137 }
1138 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1139 }
1140 break;
1141 }
1142 case OMX_QTIIndexParamColorSpaceConversion:
1143 {
1144 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1145 csc_enable = pParam->bEnable;
1146 DEBUG_PRINT_INFO("CSC settings: Enabled : %d ", pParam->bEnable);
1147 break;
1148 }
1149 case OMX_QTIIndexParamEnableLinearColorFormat:
1150 {
1151 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1152 mUseLinearColorFormat = pParam->bEnable ? REQUEST_LINEAR_COLOR_ALL : 0;
1153 DEBUG_PRINT_INFO("Linear Color Format Enabled : %d ", pParam->bEnable);
1154 break;
1155 }
1156 case OMX_QTIIndexParamNativeRecorder:
1157 {
1158 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1159 if (!set_native_recoder(pParam->bEnable)) {
1160 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamNativeRecorder failed");
1161 return false;
1162 }
1163 DEBUG_PRINT_INFO("Native recorder encode session %d", pParam->bEnable);
1164 break;
1165 }
1166 case OMX_QTIIndexParamVbvDelay:
1167 {
1168 OMX_EXTNINDEX_VIDEO_VBV_DELAY *pParam =
1169 (OMX_EXTNINDEX_VIDEO_VBV_DELAY*)paramData;
1170 if (!venc_set_vbv_delay(pParam->nVbvDelay)) {
1171 DEBUG_PRINT_ERROR("Setting OMX_QTIIndexParamVbvDelay failed");
1172 return false;
1173 }
1174 break;
1175 }
1176 default:
1177 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1178 index);
1179 break;
1180 }
1181
1182 return true;
1183 }
1184
venc_set_inband_video_header(OMX_BOOL enable)1185 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
1186 {
1187 struct v4l2_control control;
1188
1189 control.id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR;
1190 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1191 if(enable) {
1192 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1193 }
1194
1195 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
1196 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
1197 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
1198 return false;
1199 }
1200 return true;
1201 }
1202
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)1203 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
1204 {
1205 struct v4l2_control control;
1206
1207 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
1208
1209 if (enable == OMX_FALSE) {
1210 /* No easy way to turn off extradata to the driver
1211 * at the moment */
1212 return false;
1213 }
1214
1215 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
1216 switch (extra_data) {
1217 case OMX_QTI_ExtraDataCategory_Advanced:
1218 control.value = EXTRADATA_ADVANCED;
1219 break;
1220 case OMX_QTI_ExtraDataCategory_Enc_ROI:
1221 control.value = EXTRADATA_ENC_INPUT_ROI;
1222 break;
1223 default:
1224 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
1225 return false;
1226 }
1227
1228 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1229 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
1230 (unsigned int)extra_data, errno);
1231 return false;
1232 }
1233
1234 return true;
1235 }
1236
venc_set_session_qp_range(OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE * qp_range)1237 bool venc_dev::venc_set_session_qp_range(OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE* qp_range)
1238 {
1239 int rc;
1240 struct v4l2_control control[2];
1241
1242 control[0].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
1243 control[0].value = qp_range->minIQP | (qp_range->minPQP << 8) | (qp_range->minBQP << 16);
1244
1245 control[1].id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
1246 control[1].value = qp_range->maxIQP | (qp_range->maxPQP << 8) | (qp_range->maxBQP << 16);
1247
1248 for(int i=0; i<2; i++) {
1249 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control[i])) {
1250 DEBUG_PRINT_ERROR("Failed to set QP %s range", i==0?"MIN":"MAX");
1251 return false;
1252 }
1253 }
1254
1255 session_ipb_qp_values.min_qp_packed = control[0].value;
1256 session_ipb_qp_values.max_qp_packed = control[1].value;
1257
1258 return true;
1259 }
1260
venc_set_profile(OMX_U32 eProfile)1261 bool venc_dev::venc_set_profile(OMX_U32 eProfile)
1262 {
1263 int rc;
1264 struct v4l2_control control;
1265
1266 DEBUG_PRINT_LOW("venc_set_profile:: eProfile = %u",
1267 (unsigned int)eProfile);
1268
1269 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1270 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
1271 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1272 control.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
1273 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1274 control.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
1275 } else {
1276 DEBUG_PRINT_ERROR("Wrong CODEC");
1277 return false;
1278 }
1279
1280 if (m_disable_hdr & ENC_HDR_DISABLE_FLAG) {
1281 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1282 if (eProfile == OMX_VIDEO_HEVCProfileMain10 ||
1283 eProfile == OMX_VIDEO_HEVCProfileMain10HDR10 ||
1284 eProfile == OMX_VIDEO_HEVCProfileMain10HDR10Plus) {
1285 DEBUG_PRINT_ERROR("%s: HDR profile unsupported", __FUNCTION__);
1286 return false;
1287 }
1288 }
1289 }
1290
1291 if (!profile_level_converter::convert_omx_profile_to_v4l2(m_sVenc_cfg.codectype, eProfile, &control.value)) {
1292 DEBUG_PRINT_ERROR("Cannot find v4l2 profile for OMX profile : %d Codec : %lu ",
1293 eProfile, m_sVenc_cfg.codectype);
1294 return false;
1295 }
1296
1297 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1298 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1299
1300 if (rc) {
1301 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1302 return false;
1303 }
1304 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1305
1306 codec_profile.profile = control.value;
1307
1308 if (venc_set_extradata_hdr10metadata(eProfile) == false) {
1309 DEBUG_PRINT_ERROR("Failed to set extradata HDR10PLUS_METADATA");
1310 return false;
1311 }
1312
1313 return true;
1314 }
1315
venc_set_level(OMX_U32 eLevel)1316 bool venc_dev::venc_set_level(OMX_U32 eLevel)
1317 {
1318 int rc;
1319 struct v4l2_control control;
1320 unsigned int tier = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH;
1321 OMX_U32 omx_profile_level = eLevel;
1322
1323 DEBUG_PRINT_LOW("venc_set_level:: eLevel = %u",
1324 (unsigned int)eLevel);
1325
1326 if (!eLevel) {
1327 DEBUG_PRINT_ERROR(" Unknown OMX level : %u" ,
1328 (unsigned int)eLevel );
1329 return true;
1330 }
1331 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1332 if(!profile_level_converter::find_tier(m_sVenc_cfg.codectype, eLevel, &tier)) {
1333 DEBUG_PRINT_ERROR("Failed to find HEVC v4l2 level tier for OMX level : %d", eLevel);
1334 return true;
1335 }
1336 /* HEVC high tier profile levels are mapped to same V4L2 profile levels as main tier profile levels */
1337 if (tier == V4L2_MPEG_VIDEO_HEVC_TIER_HIGH)
1338 omx_profile_level = eLevel >> 1;
1339 }
1340 if (!profile_level_converter::convert_omx_level_to_v4l2(m_sVenc_cfg.codectype, omx_profile_level, &control.value)) {
1341 DEBUG_PRINT_ERROR("Failed to find v4l2 level for OMX level : %d" \
1342 " Codec : %lu", eLevel, m_sVenc_cfg.codectype);
1343 return true;
1344 }
1345
1346 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1347 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
1348 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1349 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
1350 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1351 control.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
1352 profile_level.tier = tier;
1353 }
1354 else {
1355 DEBUG_PRINT_ERROR("Wrong CODEC");
1356 return false;
1357 }
1358
1359 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d",
1360 control.id, control.value);
1361 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1362 if (rc) {
1363 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d",
1364 control.id, control.value);
1365 return false;
1366 }
1367 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d",
1368 control.id, control.value);
1369
1370 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1371 struct v4l2_control control_tier = {
1372 .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER,
1373 .value = (signed int)tier
1374 };
1375 DEBUG_PRINT_LOW("Calling IOCTL set tier control for HEVC, id %#x, value %d",
1376 control_tier.id, control_tier.value);
1377
1378 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_tier);
1379 if (rc) {
1380 DEBUG_PRINT_ERROR("Failed to set tier control for HEVC, id %#x, value %d",
1381 control_tier.id, control_tier.value);
1382 } else {
1383 profile_level.tier = control_tier.value;
1384 }
1385 }
1386 profile_level.level = control.value;
1387 return true;
1388 }
1389
venc_set_grid_enable()1390 bool venc_dev::venc_set_grid_enable()
1391 {
1392 int rc;
1393 struct v4l2_control control;
1394
1395 DEBUG_PRINT_LOW("venc_set_grid_enable");
1396 control.id = V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE;
1397 control.value = 1; // TODO: DO we need to get this value from input argument?
1398 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1399
1400 if (rc) {
1401 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1402 return false;
1403 }
1404
1405 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1406 mIsGridset = true;
1407 return true;
1408 }
1409
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)1410 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
1411 {
1412 int rc = 0;
1413 struct v4l2_control control;
1414
1415 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
1416
1417 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
1418 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
1419 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
1420 } else if (!enable) {
1421 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
1422 } else {
1423 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
1424 return false;
1425 }
1426
1427 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
1428
1429 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1430 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1431
1432 if (rc) {
1433 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1434 return false;
1435 }
1436
1437 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1438 entropy.longentropysel = control.value;
1439
1440 return true;
1441 }
1442
venc_set_multislice_cfg(OMX_U32 nSlicemode,OMX_U32 nSlicesize)1443 bool venc_dev::venc_set_multislice_cfg(OMX_U32 nSlicemode, OMX_U32 nSlicesize)
1444 {
1445 int rc;
1446 int slice_id = 0;
1447 struct v4l2_control control;
1448 bool status = true;
1449
1450 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 || nSlicesize == 0) {
1451 nSlicemode = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
1452 nSlicesize = 0;
1453 }
1454
1455 if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
1456 if (!venc_validate_range(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, nSlicesize)) {
1457 DEBUG_PRINT_ERROR("Invalid settings, hardware doesn't support %u as slicesize", nSlicesize);
1458 return false;
1459 }
1460 slice_id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
1461
1462 } else if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
1463 if (!venc_validate_range(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, nSlicesize)) {
1464 DEBUG_PRINT_ERROR("Invalid settings, hardware doesn't support %u as slicesize", nSlicesize);
1465 return false;
1466 }
1467 slice_id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
1468
1469 } else if (nSlicesize) {
1470 DEBUG_PRINT_ERROR("Invalid settings, unexpected slicemode = %u and slice size = %u", nSlicemode, nSlicesize);
1471 return false;
1472 }
1473
1474 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
1475 control.value = nSlicemode;
1476
1477 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1478 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1479
1480 if (rc) {
1481 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1482 return false;
1483 }
1484
1485 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1486
1487 if (nSlicemode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
1488 return status;
1489 }
1490
1491 control.id = slice_id;
1492 control.value = nSlicesize;
1493
1494 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
1495 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1496
1497 if (rc) {
1498 DEBUG_PRINT_ERROR("Failed to set control");
1499 return false;
1500 }
1501
1502 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1503
1504 multislice.mslice_mode = nSlicemode;
1505 multislice.mslice_size = nSlicesize;
1506
1507 return status;
1508 }
1509
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)1510 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
1511 {
1512 bool status = true;
1513 struct venc_headerextension hec_cfg;
1514 struct venc_multiclicecfg multislice_cfg;
1515 int rc;
1516 OMX_U32 resynchMarkerSpacingBytes = 0;
1517 struct v4l2_control control;
1518
1519 memset(&control, 0, sizeof(control));
1520
1521 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
1522 if (error_resilience->bEnableHEC) {
1523 hec_cfg.header_extension = 1;
1524 } else {
1525 hec_cfg.header_extension = 0;
1526 }
1527
1528 hec.header_extension = error_resilience->bEnableHEC;
1529 }
1530
1531 if (error_resilience->bEnableRVLC) {
1532 DEBUG_PRINT_ERROR("RVLC is not Supported");
1533 return false;
1534 }
1535
1536 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
1537 (error_resilience->bEnableDataPartitioning)) {
1538 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
1539 return false;
1540 }
1541
1542 if (error_resilience->nResynchMarkerSpacing) {
1543 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
1544 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
1545 }
1546
1547 status = venc_set_multislice_cfg(V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, resynchMarkerSpacingBytes);
1548
1549 return status;
1550 }
1551
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)1552 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
1553 {
1554 int rc;
1555 struct v4l2_control control;
1556 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
1557 control.value=0;
1558
1559 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
1560 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
1561 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
1562 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
1563 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
1564 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
1565 }
1566
1567 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1568 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1569
1570 if (rc) {
1571 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1572 return false;
1573 }
1574
1575 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1576
1577 dbkfilter.db_mode=control.value;
1578
1579 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
1580 control.value=0;
1581
1582 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1583 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1584
1585 if (rc) {
1586 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1587 return false;
1588 }
1589
1590 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1591 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
1592 control.value=0;
1593 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1594 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1595
1596 if (rc) {
1597 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
1598 return false;
1599 }
1600
1601 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1602
1603
1604 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
1605 return true;
1606 }
1607
venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat)1608 unsigned long venc_dev::venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat)
1609 {
1610 unsigned long codectype = V4L2_PIX_FMT_H264;
1611
1612 switch ((int)eCompressionFormat) {
1613 case OMX_VIDEO_CodingAVC:
1614 codectype = V4L2_PIX_FMT_H264;
1615 break;
1616 case OMX_VIDEO_CodingVP8:
1617 codectype = V4L2_PIX_FMT_VP8;
1618 break;
1619 case OMX_VIDEO_CodingVP9:
1620 codectype = V4L2_PIX_FMT_VP9;
1621 break;
1622 case OMX_VIDEO_CodingHEVC:
1623 case OMX_VIDEO_CodingImageHEIC:
1624 codectype = V4L2_PIX_FMT_HEVC;
1625 break;
1626 default:
1627 DEBUG_PRINT_ERROR("Unsupported eCompressionFormat %#x", eCompressionFormat);
1628 codectype = V4L2_PIX_FMT_H264;
1629 break;
1630 }
1631
1632 return codectype;
1633 }
1634
venc_set_bitrate_savings_mode(OMX_U32 bitrateSavingEnable)1635 bool venc_dev::venc_set_bitrate_savings_mode(OMX_U32 bitrateSavingEnable)
1636 {
1637 struct v4l2_control control;
1638 int rc = 0;
1639
1640 DEBUG_PRINT_LOW("Set bitrate savings %d", bitrateSavingEnable);
1641 control.id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS;
1642 control.value = bitrateSavingEnable;
1643 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1644 if (rc) {
1645 DEBUG_PRINT_HIGH("Non-Fatal: Request to set bitrate savings failed");
1646 }
1647 mBitrateSavingsEnable = bitrateSavingEnable;
1648
1649 return true;
1650 }
1651
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)1652 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
1653 {
1654 bool status = true;
1655 struct v4l2_control control;
1656 int rc = 0;
1657
1658 control.id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
1659 control.value = !!((OMX_U32)eControlRate ^ (OMX_U32)OMX_Video_ControlRateDisable);
1660 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1661 if (rc) {
1662 DEBUG_PRINT_ERROR("Failed to set RC_ENABLE");
1663 return false;
1664 }
1665
1666 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
1667 int temp = eControlRate;
1668 switch ((OMX_U32)eControlRate) {
1669 case OMX_Video_ControlRateDisable:
1670 control.value = -1;
1671 break;
1672 case OMX_Video_ControlRateVariableSkipFrames:
1673 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
1674 break;
1675 case OMX_Video_ControlRateVariable:
1676 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
1677 break;
1678 case OMX_Video_ControlRateConstantSkipFrames:
1679 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR;
1680 break;
1681 case OMX_Video_ControlRateConstant:
1682 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
1683 break;
1684 case QOMX_Video_ControlRateMaxBitrate:
1685 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR;
1686 break;
1687 case QOMX_Video_ControlRateMaxBitrateSkipFrames:
1688 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR;
1689 break;
1690 case OMX_Video_ControlRateConstantQuality:
1691 control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CQ;
1692 break;
1693 default:
1694 status = false;
1695 break;
1696 }
1697
1698 if (status && control.value != -1) {
1699
1700 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1701 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1702
1703 if (rc) {
1704 DEBUG_PRINT_ERROR("Failed to set control");
1705 return false;
1706 }
1707
1708 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1709
1710 rate_ctrl.rcmode = control.value;
1711 }
1712
1713 venc_set_bitrate_savings_mode(mBitrateSavingsEnable);
1714
1715 return status;
1716 }
1717
venc_set_aspectratio(void * nSar)1718 bool venc_dev::venc_set_aspectratio(void *nSar)
1719 {
1720 int rc;
1721 struct v4l2_control control;
1722 struct v4l2_ext_control ctrl[2];
1723 struct v4l2_ext_controls controls;
1724 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
1725
1726 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
1727
1728 ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
1729 ctrl[0].value = sar->nSARWidth;
1730 ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
1731 ctrl[1].value = sar->nSARHeight;
1732
1733 controls.count = 2;
1734 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
1735 controls.controls = ctrl;
1736
1737 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
1738 controls.controls[0].id, controls.controls[0].value,
1739 controls.controls[1].id, controls.controls[1].value);
1740
1741 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
1742 if (rc) {
1743 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
1744 return false;
1745 }
1746
1747 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
1748 controls.controls[0].id, controls.controls[0].value,
1749 controls.controls[1].id, controls.controls[1].value);
1750 return true;
1751 }
1752
venc_set_lowlatency_mode(OMX_BOOL enable)1753 bool venc_dev::venc_set_lowlatency_mode(OMX_BOOL enable)
1754 {
1755 int rc = 0;
1756 struct v4l2_control control;
1757
1758 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
1759 if (enable)
1760 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1761 else
1762 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1763
1764 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
1765 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1766 if (rc) {
1767 DEBUG_PRINT_ERROR("Failed to set lowlatency control");
1768 return false;
1769 }
1770 low_latency_mode = enable;
1771 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
1772
1773 return true;
1774 }
1775
venc_set_vui_timing_info(OMX_BOOL enable)1776 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
1777 {
1778 struct v4l2_control control;
1779 int rc = 0;
1780 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO;
1781
1782 if (enable)
1783 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
1784 else
1785 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
1786
1787 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
1788 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1789 if (rc) {
1790 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
1791 return false;
1792 }
1793 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
1794 return true;
1795 }
1796
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)1797 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
1798 {
1799 struct v4l2_control control;
1800 int rc = 0;
1801 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
1802 control.value = nPeakBitrate;
1803
1804 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
1805
1806 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1807 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1808
1809 if (rc) {
1810 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
1811 return false;
1812 }
1813
1814 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1815
1816 return true;
1817 }
1818
venc_set_vpx_error_resilience(OMX_BOOL enable)1819 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
1820 {
1821 struct v4l2_control control;
1822 int rc = 0;
1823 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
1824
1825 if (enable)
1826 control.value = 1;
1827 else
1828 control.value = 0;
1829
1830 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
1831
1832 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1833
1834 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1835 if (rc) {
1836 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
1837 return false;
1838 }
1839 vpx_err_resilience.enable = 1;
1840 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1841 return true;
1842 }
1843
venc_set_vbv_delay(OMX_U32 nVbvDelay)1844 bool venc_dev::venc_set_vbv_delay(OMX_U32 nVbvDelay)
1845 {
1846 int rc = 0;
1847 struct v4l2_control control;
1848
1849 control.id = V4L2_CID_MPEG_VIDEO_VBV_DELAY;
1850 control.value = nVbvDelay;
1851
1852 DEBUG_PRINT_LOW("venc_set_vbv_delay: vbvdelay = %u", (unsigned int)control.value);
1853
1854 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
1855 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1856
1857 if (rc) {
1858 DEBUG_PRINT_ERROR("Failed to set vbv delay");
1859 return false;
1860 }
1861
1862 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
1863 return true;
1864 }
1865