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