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