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