1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2016, 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 met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of The Linux Foundation nor
12       the names of its contributors may be used to endorse or promote
13       products derived from this software without specific prior written
14       permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/prctl.h>
32 #include <sys/eventfd.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include "video_encoder_device_v4l2.h"
36 #include "omx_video_encoder.h"
37 #include <media/msm_vidc.h>
38 #ifdef USE_ION
39 #include <linux/msm_ion.h>
40 #endif
41 #include <media/msm_media_info.h>
42 #include <cutils/properties.h>
43 #include <media/hardware/HardwareAPI.h>
44 
45 #ifdef _ANDROID_
46 #include <media/hardware/HardwareAPI.h>
47 #include <gralloc_priv.h>
48 #endif
49 
50 #include <qdMetaData.h>
51 
52 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
53 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
54 #define MAXDPB 16
55 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
56 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
57 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
58 #define MAX_PROFILE_PARAMS 6
59 #define MPEG4_SP_START 0
60 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
61 #define H263_BP_START 0
62 #define H264_BP_START 0
63 #define H264_HP_START (H264_BP_START + 18)
64 #define H264_MP_START (H264_BP_START + 36)
65 #define HEVC_MAIN_START 0
66 #define HEVC_MAIN10_START (HEVC_MAIN_START + 13)
67 #define POLL_TIMEOUT 1000
68 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
69 
70 #define SZ_4K 0x1000
71 #define SZ_1M 0x100000
72 
73 /* MPEG4 profile and level table*/
74 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
75     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
76     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
77     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
78     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
79     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
80     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
81     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
82     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
83     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
84     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
85     /* Please update MPEG4_ASP_START accordingly, while adding new element */
86     {0,0,0,0,0,0},
87 
88     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
89     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
90     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
91     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
92     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
93     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
94     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
95     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
96     {0,0,0,0,0,0},
97 };
98 
99 /* H264 profile and level table*/
100 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
101     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
102     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
103     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
104     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
105     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
106     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
107     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
108     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
109     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
110     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
111     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
112     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
113     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
114     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
115     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
116     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
117     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
118     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
119     /* Please update H264_HP_START accordingly, while adding new element */
120     {0,0,0,0,0,0},
121 
122     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
123     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
124     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
125     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
126     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
127     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
128     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
129     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
130     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
131     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
132     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
133     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
134     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
135     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
136     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
137     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
138     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
139     /* Please update H264_MP_START accordingly, while adding new element */
140     {0,0,0,0,0,0},
141 
142     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
143     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
144     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
145     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
146     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
147     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
148     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
149     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
150     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
151     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
152     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
153     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
154     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
155     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
156     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
157     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
158     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
159     {0,0,0,0,0,0}
160 
161 };
162 
163 /* H263 profile and level table*/
164 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
165     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
166     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
167     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
168     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
169     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
170     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
171     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
172     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
173     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
174     {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
175     {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
176     {0,0,0,0,0,0}
177 };
178 
179 /* HEVC profile and level table*/
180 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
181     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
182     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
183     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
184     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
185     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
186     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
187     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
188     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
189     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
190     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
191     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
192     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
193     {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
194     {138240,4147200,240000000,OMX_VIDEO_HEVCHighTierLevel52,OMX_VIDEO_HEVCProfileMain,0},
195     /* Please update HEVC_MAIN_START accordingly, while adding new element */
196     {0,0,0,0,0},
197 
198     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
199     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
200     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
201     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
202     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
203     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
204     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
205     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
206     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
207     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
208     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
209     {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
210     {0,0,0,0,0},
211 };
212 
213 
214 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
215 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
216 
217 #define BUFFER_LOG_LOC "/data/misc/media"
218 
219 //constructor
venc_dev(class omx_venc * venc_class)220 venc_dev::venc_dev(class omx_venc *venc_class):mInputExtradata(venc_class), mOutputExtradata(venc_class)
221 {
222     //nothing to do
223     int i = 0;
224     venc_handle = venc_class;
225     etb = ebd = ftb = fbd = 0;
226     m_poll_efd = -1;
227 
228     struct v4l2_control control;
229     for (i = 0; i < MAX_PORT; i++)
230         streaming[i] = false;
231 
232     stopped = 1;
233     paused = false;
234     async_thread_created = false;
235     async_thread_force_stop = false;
236     color_format = 0;
237     hw_overload = false;
238     mBatchSize = 0;
239     m_profile_set = false;
240     m_level_set = false;
241     rc_off_level = 0;
242     pthread_mutex_init(&pause_resume_mlock, NULL);
243     pthread_cond_init(&pause_resume_cond, NULL);
244     memset(&idrperiod, 0, sizeof(idrperiod));
245     memset(&multislice, 0, sizeof(multislice));
246     memset (&slice_mode, 0 , sizeof(slice_mode));
247     memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
248     memset(&rate_ctrl, 0, sizeof(rate_ctrl));
249     memset(&bitrate, 0, sizeof(bitrate));
250     memset(&intra_period, 0, sizeof(intra_period));
251     memset(&codec_profile, 0, sizeof(codec_profile));
252     memset(&set_param, 0, sizeof(set_param));
253     memset(&time_inc, 0, sizeof(time_inc));
254     memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
255     memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
256     memset(&session_qp, 0, sizeof(session_qp));
257     memset(&entropy, 0, sizeof(entropy));
258     memset(&dbkfilter, 0, sizeof(dbkfilter));
259     memset(&intra_refresh, 0, sizeof(intra_refresh));
260     memset(&hec, 0, sizeof(hec));
261     memset(&voptimecfg, 0, sizeof(voptimecfg));
262     memset(&capability, 0, sizeof(capability));
263     memset(&m_debug,0,sizeof(m_debug));
264     memset(&hier_layers,0,sizeof(hier_layers));
265     is_searchrange_set = false;
266     enable_mv_narrow_searchrange = false;
267     supported_rc_modes = RC_ALL;
268     memset(&vqzip_sei_info, 0, sizeof(vqzip_sei_info));
269     memset(&ltrinfo, 0, sizeof(ltrinfo));
270     memset(&fd_list, 0, sizeof(fd_list));
271     memset(&hybrid_hp, 0, sizeof(hybrid_hp));
272     sess_priority.priority = 1; //default to non-realtime
273     operating_rate = 0;
274     memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
275     memset(&color_space, 0x0, sizeof(color_space));
276 
277     char property_value[PROPERTY_VALUE_MAX] = {0};
278     property_get("vidc.enc.log.in", property_value, "0");
279     m_debug.in_buffer_log = atoi(property_value);
280 
281     property_get("vidc.enc.log.out", property_value, "0");
282     m_debug.out_buffer_log = atoi(property_value);
283 
284     property_get("vidc.enc.log.extradata", property_value, "0");
285     m_debug.extradata_log = atoi(property_value);
286 
287     property_get("vidc.enc.log.roiqp", property_value, "0");
288     m_debug.roiqp_log = atoi(property_value);
289 #ifdef _UBWC_
290     property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
291     if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
292         !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
293         is_gralloc_source_ubwc = 0;
294     } else {
295         is_gralloc_source_ubwc = 1;
296     }
297 #else
298     is_gralloc_source_ubwc = 0;
299 #endif
300 
301     property_get("persist.vidc.enc.csc.enable", property_value, "0");
302     if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
303             !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
304         is_csc_enabled = 1;
305     } else {
306         is_csc_enabled = 0;
307     }
308     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
309              "%s", BUFFER_LOG_LOC);
310 
311     mUseAVTimerTimestamps = false;
312 }
313 
~venc_dev()314 venc_dev::~venc_dev()
315 {
316 }
317 
async_venc_message_thread(void * input)318 void* venc_dev::async_venc_message_thread (void *input)
319 {
320     struct venc_msg venc_msg;
321     omx_video* omx_venc_base = NULL;
322     omx_venc *omx = reinterpret_cast<omx_venc*>(input);
323     omx_venc_base = reinterpret_cast<omx_video*>(input);
324     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
325 
326     prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
327     struct v4l2_plane plane[VIDEO_MAX_PLANES];
328     struct pollfd pfds[2];
329     struct v4l2_buffer v4l2_buf;
330     struct v4l2_event dqevent;
331     struct statistics stats;
332     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
333     pfds[1].events = POLLIN | POLLERR;
334     pfds[0].fd = omx->handle->m_nDriver_fd;
335     pfds[1].fd = omx->handle->m_poll_efd;
336     int error_code = 0,rc=0;
337 
338     memset(&stats, 0, sizeof(statistics));
339     memset(&v4l2_buf, 0, sizeof(v4l2_buf));
340 
341     while (!omx->handle->async_thread_force_stop) {
342         pthread_mutex_lock(&omx->handle->pause_resume_mlock);
343 
344         if (omx->handle->paused) {
345             venc_msg.msgcode = VEN_MSG_PAUSE;
346             venc_msg.statuscode = VEN_S_SUCCESS;
347 
348             if (omx->async_message_process(input, &venc_msg) < 0) {
349                 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
350                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
351                 break;
352             }
353 
354             /* Block here until the IL client resumes us again */
355             pthread_cond_wait(&omx->handle->pause_resume_cond,
356                     &omx->handle->pause_resume_mlock);
357 
358             venc_msg.msgcode = VEN_MSG_RESUME;
359             venc_msg.statuscode = VEN_S_SUCCESS;
360 
361             if (omx->async_message_process(input, &venc_msg) < 0) {
362                 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
363                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
364                 break;
365             }
366             memset(&stats, 0, sizeof(statistics));
367         }
368 
369         pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
370 
371         rc = poll(pfds, 2, POLL_TIMEOUT);
372 
373         if (!rc) {
374             DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
375                     omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
376             continue;
377         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
378             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
379             break;
380         }
381 
382         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
383             DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited");
384             break;
385         }
386 
387         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
388             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
389             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
390             v4l2_buf.length = omx->handle->num_output_planes;
391             v4l2_buf.m.planes = plane;
392 
393             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
394                 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
395                 venc_msg.statuscode=VEN_S_SUCCESS;
396                 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
397                 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
398                 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
399                     omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
400                 } else {
401                     omxhdr->pPlatformPrivate = 0;
402                 }
403                 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
404                 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
405                 venc_msg.buf.flags = 0;
406                 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
407                 venc_msg.buf.clientdata=(void*)omxhdr;
408                 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
409 
410                 /* TODO: ideally report other types of frames as well
411                  * for now it doesn't look like IL client cares about
412                  * other types
413                  */
414                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
415                     venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
416 
417                 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
418                     venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
419 
420                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
421                     venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
422 
423                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
424                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
425 
426                 if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused)
427                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
428 
429                 if (omxhdr->nFilledLen)
430                     venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
431 
432                 omx->handle->fbd++;
433                 stats.bytes_generated += venc_msg.buf.len;
434 
435                 if (omx->async_message_process(input,&venc_msg) < 0) {
436                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
437                     break;
438                 }
439             }
440         }
441 
442         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
443             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
444             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
445             v4l2_buf.m.planes = plane;
446             v4l2_buf.length = omx->handle->num_input_planes;
447 
448             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
449                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
450                 venc_msg.statuscode=VEN_S_SUCCESS;
451                 omx->handle->ebd++;
452 
453                 if (omx->handle->mBatchSize) {
454                     int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index);
455                     if (bufIndex < 0) {
456                         DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index);
457                         break;
458                     }
459                     if (omx->handle->mBatchInfo.isPending(bufIndex)) {
460                         DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending",
461                                 bufIndex, v4l2_buf.index);
462                         //do not return to client yet
463                         continue;
464                     }
465                     v4l2_buf.index = bufIndex;
466                 }
467                 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
468                     omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
469                 else
470                     omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
471 
472                 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
473                 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
474                     omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
475                     omx->handle->mInputExtradata.put((char *)omxhdr->pPlatformPrivate);
476                 } else {
477                     omxhdr->pPlatformPrivate = 0;
478                 }
479 
480                 venc_msg.buf.clientdata=(void*)omxhdr;
481 
482                 DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index);
483                 if (omx->async_message_process(input,&venc_msg) < 0) {
484                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
485                     break;
486                 }
487             }
488         }
489 
490         if (pfds[0].revents & POLLPRI) {
491             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
492 
493             if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
494                 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
495                 venc_msg.statuscode = VEN_S_SUCCESS;
496 
497                 if (omx->async_message_process(input,&venc_msg) < 0) {
498                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
499                     break;
500                 }
501 
502                 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
503                 venc_msg.statuscode = VEN_S_SUCCESS;
504 
505                 if (omx->async_message_process(input,&venc_msg) < 0) {
506                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
507                     break;
508                 }
509             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
510                 DEBUG_PRINT_ERROR("HW Overload received");
511                 venc_msg.statuscode = VEN_S_EFAIL;
512                 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
513 
514                 if (omx->async_message_process(input,&venc_msg) < 0) {
515                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
516                     break;
517                 }
518             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){
519                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
520                 venc_msg.msgcode = VEN_MSG_INDICATION;
521                 venc_msg.statuscode=VEN_S_EFAIL;
522 
523                 if (omx->async_message_process(input,&venc_msg) < 0) {
524                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
525                     break;
526                 }
527             }
528         }
529 
530         /* calc avg. fps, bitrate */
531         struct timeval tv;
532         gettimeofday(&tv,NULL);
533         OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) -
534                 (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec));
535         if (time_diff >= 5000000) {
536             if (stats.prev_tv.tv_sec) {
537                 OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd;
538                 float framerate = num_fbd * 1000000/(float)time_diff;
539                 OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate;
540                 DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d",
541                     framerate, bitrate);
542             }
543             stats.prev_tv = tv;
544             stats.bytes_generated = 0;
545             stats.prev_fbd = omx->handle->fbd;
546         }
547 
548     }
549 
550     DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
551     return NULL;
552 }
553 
554 static const int event_type[] = {
555     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
556     V4L2_EVENT_MSM_VIDC_SYS_ERROR
557 };
558 
subscribe_to_events(int fd)559 static OMX_ERRORTYPE subscribe_to_events(int fd)
560 {
561     OMX_ERRORTYPE eRet = OMX_ErrorNone;
562     struct v4l2_event_subscription sub;
563     int array_sz = sizeof(event_type)/sizeof(int);
564     int i,rc;
565     memset(&sub, 0, sizeof(sub));
566 
567     if (fd < 0) {
568        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
569         return OMX_ErrorBadParameter;
570     }
571 
572     for (i = 0; i < array_sz; ++i) {
573         memset(&sub, 0, sizeof(sub));
574         sub.type = event_type[i];
575         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
576 
577         if (rc) {
578            DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
579             break;
580         }
581     }
582 
583     if (i < array_sz) {
584         for (--i; i >=0 ; i--) {
585             memset(&sub, 0, sizeof(sub));
586             sub.type = event_type[i];
587             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
588 
589             if (rc)
590                DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
591         }
592 
593         eRet = OMX_ErrorNotImplemented;
594     }
595 
596     return eRet;
597 }
598 
append_mbi_extradata(void * dst,struct msm_vidc_extradata_header * src)599 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
600 {
601     OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
602 
603     if (!dst || !src)
604         return 0;
605 
606     /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
607      * targets, since the payload format will be different */
608     mbi->nFormat = 1;
609     mbi->nDataSize = src->data_size;
610     memcpy(&mbi->data, &src->data, src->data_size);
611 
612     return mbi->nDataSize + sizeof(*mbi);
613 }
614 
handle_input_extradata(void * buffer,int fd)615 bool venc_dev::handle_input_extradata(void *buffer, int fd)
616 {
617     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
618     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
619     ssize_t consumed_len = 0;
620     int enable = 0, i = 0;
621     int height = 0, width = 0;
622     char *userptr;
623     int extra_fd;
624     unsigned offset;
625     ssize_t extra_size;
626     struct v4l2_control control;
627 
628     memset(&control, 0, sizeof(control));
629     control.id =  V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
630     if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control) < 0) {
631         return false;
632     }
633 
634     if (!(control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
635         control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI ||
636         control.value == V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP ||
637         control.value == V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP)) {
638         DEBUG_PRINT_LOW("Input extradata not enabled");
639         return true;
640     }
641 
642     /*
643      * At this point encoder component doesn't know where the extradata is
644      * located in YUV buffer. For all practical usecases, decoder appends
645      * extradata after nFilledLen which is calcualted as 32 aligned height
646      * and width * 3 / 2. Hence start looking for extradata from this point.
647      */
648 
649     height = ALIGN(m_sVenc_cfg.input_height, 32);
650     width = ALIGN(m_sVenc_cfg.input_width, 32);
651 
652     int rc = mInputExtradata.get(buffer, &userptr, &extra_fd, &offset, &extra_size);
653     if (rc != OMX_ErrorNone) {
654         DEBUG_PRINT_ERROR("Unable to get extradata memory 4");
655         return false;
656     }
657     unsigned char *pVirt;
658     int size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
659     pVirt= (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
660 
661     p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned long)(pVirt + ((width * height * 3) / 2) + 3)&(~3));
662     char *p_extradata = userptr;
663     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
664     if (p_extra) {
665         while ((consumed_len < extra_size)
666             && (p_extra->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
667             DEBUG_PRINT_LOW("Extradata Type = 0x%x", (OMX_QCOM_EXTRADATATYPE)p_extra->eType);
668             switch ((OMX_QCOM_EXTRADATATYPE)p_extra->eType) {
669             case OMX_ExtraDataFrameDimension:
670             {
671                 struct msm_vidc_extradata_index *payload;
672                 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *framedimension_format;
673                 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_extradata_index) + 3)&(~3);
674                 data->nVersion.nVersion = OMX_SPEC_VERSION;
675                 data->nPortIndex = 0;
676                 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_INDEX;
677                 data->nDataSize = sizeof(struct msm_vidc_input_crop_payload);
678                 framedimension_format = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)p_extra->data;
679                 payload = (struct msm_vidc_extradata_index *)(data->data);
680                 payload->type = (msm_vidc_extradata_type)MSM_VIDC_EXTRADATA_INPUT_CROP;
681                 payload->input_crop.left = framedimension_format->nDecWidth;
682                 payload->input_crop.top = framedimension_format->nDecHeight;
683                 payload->input_crop.width = framedimension_format->nActualWidth;
684                 payload->input_crop.height = framedimension_format->nActualHeight;
685                 DEBUG_PRINT_LOW("Height = %d Width = %d Actual Height = %d Actual Width = %d",
686                     framedimension_format->nDecWidth, framedimension_format->nDecHeight,
687                     framedimension_format->nActualWidth, framedimension_format->nActualHeight);
688                 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
689                 break;
690             }
691             case OMX_ExtraDataQP:
692             {
693                 OMX_QCOM_EXTRADATA_QP * qp_payload = NULL;
694                 struct msm_vidc_frame_qp_payload *payload;
695                 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_frame_qp_payload) + 3)&(~3);
696                 data->nVersion.nVersion = OMX_SPEC_VERSION;
697                 data->nPortIndex = 0;
698                 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_FRAME_QP;
699                 data->nDataSize = sizeof(struct  msm_vidc_frame_qp_payload);
700                 qp_payload = (OMX_QCOM_EXTRADATA_QP *)p_extra->data;
701                 payload = (struct  msm_vidc_frame_qp_payload *)(data->data);
702                 payload->frame_qp = qp_payload->nQP;
703                 DEBUG_PRINT_LOW("Frame QP = %d", payload->frame_qp);
704                 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
705                 break;
706             }
707             case OMX_ExtraDataVQZipSEI:
708                 DEBUG_PRINT_LOW("VQZIP SEI Found ");
709                 mInputExtradata.vqzip_sei_found = true;
710                 break;
711             default:
712                 break;
713             }
714             consumed_len += p_extra->nSize;
715             p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize);
716         }
717 
718         if (control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
719             control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI) {
720             if (!mInputExtradata.vqzip_sei_found) {
721                 DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session");
722                 munmap(pVirt, size);
723                 mInputExtradata.put(userptr);
724                 return false;
725             }
726 #ifdef _VQZIP_
727             data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) +  sizeof(struct VQZipStats) + 3)&(~3);
728             data->nVersion.nVersion = OMX_SPEC_VERSION;
729             data->nPortIndex = 0;
730             data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_YUVSTATS_INFO;
731             data->nDataSize = sizeof(struct VQZipStats);
732             vqzip.fill_stats_data((void*)pVirt, (void*) data->data);
733             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
734 #endif
735         }
736 
737         data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
738         data->nVersion.nVersion = OMX_SPEC_VERSION;
739         data->eType = OMX_ExtraDataNone;
740         data->nDataSize = 0;
741         data->data[0] = 0;
742 
743     }
744     munmap(pVirt, size);
745     mInputExtradata.put(userptr);
746     return true;
747 }
748 
handle_output_extradata(void * buffer)749 bool venc_dev::handle_output_extradata(void *buffer)
750 {
751     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
752     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
753     char *extradata_uaddr = (char *)p_bufhdr->pPlatformPrivate;
754 
755     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
756                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
757 
758     if (mOutputExtradata.getBufferSize() >
759             (ssize_t)(p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4))) {
760         DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
761         p_extra = NULL;
762         return false;
763     } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
764         /* A lot of the code below assumes this condition, so error out if it's not met */
765         DEBUG_PRINT_ERROR("Extradata ABI mismatch");
766         return false;
767     }
768 
769     struct msm_vidc_extradata_header *p_extradata = NULL;
770     do {
771         p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
772             ((char *)p_extradata) + p_extradata->size : extradata_uaddr);
773 
774         switch (p_extradata->type) {
775             case MSM_VIDC_EXTRADATA_METADATA_MBI:
776             {
777                 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
778                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
779                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
780                 p_extra->nPortIndex = OMX_DirOutput;
781                 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
782                 p_extra->nDataSize = payloadSize;
783                 break;
784             }
785             case MSM_VIDC_EXTRADATA_METADATA_LTR:
786             {
787                 *p_extra->data = *p_extradata->data;
788                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
789                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
790                 p_extra->nPortIndex = OMX_DirOutput;
791                 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
792                 p_extra->nDataSize = p_extradata->data_size;
793                 break;
794             }
795             case MSM_VIDC_EXTRADATA_NONE:
796                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
797                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
798                 p_extra->nPortIndex = OMX_DirOutput;
799                 p_extra->eType = OMX_ExtraDataNone;
800                 p_extra->nDataSize = 0;
801                 break;
802             default:
803                 /* No idea what this stuff is, just skip over it */
804                 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
805                         p_extradata->type);
806                 continue;
807         }
808 
809         p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
810     } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
811 
812     /* Just for debugging: Traverse the list of extra datas  and spit it out onto log */
813     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
814                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
815     while(p_extra->eType != OMX_ExtraDataNone)
816     {
817         DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
818                 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
819                 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
820 
821         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
822                 p_extra->nSize);
823     }
824     mOutputExtradata.put(extradata_uaddr);
825     return true;
826 }
827 
venc_set_format(int format)828 int venc_dev::venc_set_format(int format)
829 {
830     int rc = true;
831 
832     if (format) {
833         color_format = format;
834 
835         switch (color_format) {
836         case NV12_128m:
837             return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m);
838         default:
839             return false;
840         }
841 
842     } else {
843         color_format = 0;
844         rc = false;
845     }
846 
847     return rc;
848 }
849 
venc_get_output_log_flag()850 bool venc_dev::venc_get_output_log_flag()
851 {
852     return (m_debug.out_buffer_log == 1);
853 }
854 
venc_output_log_buffers(const char * buffer_addr,int buffer_len)855 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
856 {
857     if (venc_handle->is_secure_session()) {
858         DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
859         return -1;
860     }
861 
862     if (!m_debug.outfile) {
863         int size = 0;
864         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
865            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
866                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
867         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
868            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
869                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
870         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
871            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
872                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
873         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
874            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
875                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
876         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
877            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
878                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
879         }
880         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
881              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
882                                 m_debug.outfile_name, size);
883         }
884         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
885         if (!m_debug.outfile) {
886             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
887                                m_debug.outfile_name, errno);
888             m_debug.outfile_name[0] = '\0';
889             return -1;
890         }
891     }
892     if (m_debug.outfile && buffer_len) {
893         DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
894         fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
895     }
896     return 0;
897 }
898 
venc_extradata_log_buffers(char * buffer_addr)899 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
900 {
901     if (!m_debug.extradatafile && m_debug.extradata_log) {
902         int size = 0;
903         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
904            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
905                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
906         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
907            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
908                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
909         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
910            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
911                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
912         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
913            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
914                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
915         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
916            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
917                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
918         }
919         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
920              DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
921                                 m_debug.extradatafile_name, size);
922         }
923 
924         m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
925         if (!m_debug.extradatafile) {
926             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
927                                m_debug.extradatafile_name, errno);
928             m_debug.extradatafile_name[0] = '\0';
929             return -1;
930         }
931     }
932 
933     if (m_debug.extradatafile) {
934         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
935         do {
936             p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
937                     ((char *)p_extra) + p_extra->nSize);
938             fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
939         } while (p_extra->eType != OMX_ExtraDataNone);
940     }
941     return 0;
942 }
943 
venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)944 int venc_dev::venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
945     int size = 0;
946     if (!roiInfo || !m_debug.roiqp_log) {
947         DEBUG_PRINT_LOW("Nothing to log");
948         return 0;
949     }
950     if (!m_debug.roiqpfile) {
951         size = snprintf(m_debug.roiqpfile_name, PROPERTY_VALUE_MAX, "%s/enc_%lu_%lu_%p.roiqp",
952                 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
953         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
954             DEBUG_PRINT_ERROR("Failed to open ROIQP file: %s for logging size:%d",
955                     m_debug.roiqpfile_name, size);
956             m_debug.roiqpfile_name[0] = '\0';
957             return -1;
958         }
959         m_debug.roiqpfile = fopen(m_debug.roiqpfile_name, "ab");
960         if (!m_debug.roiqpfile) {
961             DEBUG_PRINT_ERROR("Failed to open ROI QP file: %s for logging errno:%d",
962                     m_debug.roiqpfile_name, errno);
963             m_debug.roiqpfile_name[0] = '\0';
964             return -1;
965         }
966     }
967     if (m_debug.roiqpfile) {
968         if (fwrite(&mInputExtradata.mDbgEtbCount, sizeof(mInputExtradata.mDbgEtbCount), 1, m_debug.roiqpfile) != 1) {
969             DEBUG_PRINT_ERROR("Unable to write to QP file");
970             return -1;
971         }
972         if (fwrite(&roiInfo->nLowerQpOffset, sizeof(roiInfo->nLowerQpOffset), 1, m_debug.roiqpfile) != 1) {
973             DEBUG_PRINT_ERROR("Unable to write to QP file");
974             return -1;
975         }
976         if (fwrite(&roiInfo->nUpperQpOffset, sizeof(roiInfo->nUpperQpOffset), 1, m_debug.roiqpfile) != 1) {
977             DEBUG_PRINT_ERROR("Unable to write to QP file");
978             return -1;
979         }
980         if (fwrite((char *)roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize, 1, m_debug.roiqpfile) != 1) {
981             DEBUG_PRINT_ERROR("Unable to write to QP file");
982             return -1;
983         }
984     }
985     return 0;
986 }
987 
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset,unsigned long inputformat)988 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset,
989         unsigned long inputformat) {
990     if (venc_handle->is_secure_session()) {
991         DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
992         return -1;
993     }
994 
995     if (!m_debug.infile) {
996         int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
997                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
998         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
999              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
1000                                 m_debug.infile_name, size);
1001         }
1002         m_debug.infile = fopen (m_debug.infile_name, "ab");
1003         if (!m_debug.infile) {
1004             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
1005             m_debug.infile_name[0] = '\0';
1006             return -1;
1007         }
1008     }
1009 
1010     if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
1011         int stride, scanlines;
1012         int color_format;
1013         unsigned long i, msize;
1014         unsigned char *pvirt = NULL, *ptemp = NULL;
1015         unsigned char *temp = (unsigned char *)pbuffer->pBuffer;
1016 
1017         switch (inputformat) {
1018             case V4L2_PIX_FMT_NV12:
1019                 color_format = COLOR_FMT_NV12;
1020                 break;
1021             case V4L2_PIX_FMT_NV12_UBWC:
1022                 color_format = COLOR_FMT_NV12_UBWC;
1023                 break;
1024             case V4L2_PIX_FMT_RGB32:
1025                 color_format = COLOR_FMT_RGBA8888;
1026                 break;
1027             case V4L2_PIX_FMT_RGBA8888_UBWC:
1028                 color_format = COLOR_FMT_RGBA8888_UBWC;
1029                 break;
1030             default:
1031                 color_format = COLOR_FMT_NV12;
1032                 DEBUG_PRINT_LOW("Default format NV12 is set for logging [%lu]", inputformat);
1033                 break;
1034         }
1035 
1036         msize = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
1037         const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
1038 
1039         if (metadatamode == 1) {
1040             pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
1041             if (pvirt == MAP_FAILED) {
1042                 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
1043                 return -1;
1044             }
1045             ptemp = pvirt;
1046         } else {
1047             ptemp = temp;
1048         }
1049 
1050         if (color_format == COLOR_FMT_NV12) {
1051             stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
1052             scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
1053 
1054             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1055                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1056                 ptemp += stride;
1057             }
1058             if (metadatamode == 1) {
1059                 ptemp = pvirt + (stride * scanlines);
1060             } else {
1061                 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
1062             }
1063             for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
1064                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1065                 ptemp += stride;
1066             }
1067         } else if (color_format == COLOR_FMT_RGBA8888) {
1068             stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width);
1069             scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height);
1070 
1071             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1072                 fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile);
1073                 ptemp += stride;
1074             }
1075         } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) {
1076             if (color_format == COLOR_FMT_NV12_UBWC) {
1077                 msize -= 2 * extra_size;
1078             }
1079             fwrite(ptemp, msize, 1, m_debug.infile);
1080         }
1081 
1082         if (metadatamode == 1 && pvirt) {
1083             munmap(pvirt, msize);
1084         }
1085     }
1086 
1087     return 0;
1088 }
1089 
venc_open(OMX_U32 codec)1090 bool venc_dev::venc_open(OMX_U32 codec)
1091 {
1092     int r;
1093     unsigned int alignment = 0,buffer_size = 0, temp =0;
1094     struct v4l2_control control;
1095     OMX_STRING device_name = (OMX_STRING)"/dev/video33";
1096     char property_value[PROPERTY_VALUE_MAX] = {0};
1097     char platform_name[PROPERTY_VALUE_MAX] = {0};
1098     FILE *soc_file = NULL;
1099     char buffer[10];
1100 
1101     property_get("ro.board.platform", platform_name, "0");
1102     property_get("vidc.enc.narrow.searchrange", property_value, "0");
1103     enable_mv_narrow_searchrange = atoi(property_value);
1104 
1105     if (!strncmp(platform_name, "msm8610", 7)) {
1106         device_name = (OMX_STRING)"/dev/video/q6_enc";
1107         supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
1108     }
1109     m_nDriver_fd = open (device_name, O_RDWR);
1110     if ((int)m_nDriver_fd < 0) {
1111         DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
1112         return false;
1113     }
1114     m_poll_efd = eventfd(0, 0);
1115     if (m_poll_efd < 0) {
1116         DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno));
1117         return false;
1118     }
1119     DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
1120 
1121     // set the basic configuration of the video encoder driver
1122     m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
1123     m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
1124     m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
1125     m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
1126     m_sVenc_cfg.fps_num = 30;
1127     m_sVenc_cfg.fps_den = 1;
1128     m_sVenc_cfg.targetbitrate = 64000;
1129     m_sVenc_cfg.inputformat= V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1130 
1131     m_codec = codec;
1132 
1133     if (codec == OMX_VIDEO_CodingMPEG4) {
1134         m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
1135         codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
1136         profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
1137         session_qp_range.minqp = 1;
1138         session_qp_range.maxqp = 31;
1139     } else if (codec == OMX_VIDEO_CodingH263) {
1140         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
1141         codec_profile.profile = VEN_PROFILE_H263_BASELINE;
1142         profile_level.level = VEN_LEVEL_H263_20;
1143         session_qp_range.minqp = 1;
1144         session_qp_range.maxqp = 31;
1145     } else if (codec == OMX_VIDEO_CodingAVC) {
1146         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
1147         codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1148         profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1149         session_qp_range.minqp = 1;
1150         session_qp_range.maxqp = 51;
1151     } else if (codec == OMX_VIDEO_CodingVP8) {
1152         m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
1153         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
1154         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
1155         session_qp_range.minqp = 1;
1156         session_qp_range.maxqp = 128;
1157     } else if (codec == OMX_VIDEO_CodingHEVC) {
1158         m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
1159         session_qp_range.minqp = 1;
1160         session_qp_range.maxqp = 51;
1161         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
1162         profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
1163     }
1164     session_qp_values.minqp = session_qp_range.minqp;
1165     session_qp_values.maxqp = session_qp_range.maxqp;
1166 
1167     int ret;
1168     ret = subscribe_to_events(m_nDriver_fd);
1169 
1170     if (ret) {
1171         DEBUG_PRINT_ERROR("Subscribe Event Failed");
1172         return false;
1173     }
1174 
1175     struct v4l2_fmtdesc fdesc;
1176     struct v4l2_format fmt;
1177     struct v4l2_requestbuffers bufreq;
1178     struct v4l2_capability cap;
1179 
1180     ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
1181 
1182     if (ret) {
1183         DEBUG_PRINT_ERROR("Failed to query capabilities");
1184     } else {
1185         DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1186                 " version = %d, capabilities = %x", cap.driver, cap.card,
1187                 cap.bus_info, cap.version, cap.capabilities);
1188     }
1189 
1190     ret=0;
1191     fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1192     fdesc.index=0;
1193 
1194     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1195         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1196                 fdesc.pixelformat, fdesc.flags);
1197         fdesc.index++;
1198     }
1199 
1200     fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1201     fdesc.index=0;
1202 
1203     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1204         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1205                 fdesc.pixelformat, fdesc.flags);
1206         fdesc.index++;
1207     }
1208 
1209     is_thulium_v1 = false;
1210     soc_file= fopen("/sys/devices/soc0/soc_id", "r");
1211     if (soc_file) {
1212         fread(buffer, 1, 4, soc_file);
1213         fclose(soc_file);
1214         if (atoi(buffer) == 246) {
1215             soc_file = fopen("/sys/devices/soc0/revision", "r");
1216             if (soc_file) {
1217                 fread(buffer, 1, 4, soc_file);
1218                 fclose(soc_file);
1219                 if (atoi(buffer) == 1) {
1220                     is_thulium_v1 = true;
1221                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
1222                 }
1223             }
1224         }
1225     }
1226 
1227     if (venc_handle->is_secure_session()) {
1228         m_sOutput_buff_property.alignment = SZ_1M;
1229         m_sInput_buff_property.alignment  = SZ_1M;
1230     } else {
1231         m_sOutput_buff_property.alignment = SZ_4K;
1232         m_sInput_buff_property.alignment  = SZ_4K;
1233     }
1234 
1235     memset(&fmt, 0, sizeof(fmt));
1236     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1237     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1238     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1239     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1240 
1241     /*TODO: Return values not handled properly in this function anywhere.
1242      * Need to handle those.*/
1243     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1244 
1245     if (ret) {
1246         DEBUG_PRINT_ERROR("Failed to set format on capture port");
1247         return false;
1248     }
1249 
1250     m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1251 
1252     memset(&fmt, 0, sizeof(fmt));
1253     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1254     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1255     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1256     fmt.fmt.pix_mp.pixelformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1257     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1258 
1259     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1260     m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1261 
1262     bufreq.memory = V4L2_MEMORY_USERPTR;
1263     bufreq.count = 2;
1264 
1265     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1266     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1267     m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1268 
1269     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1270     bufreq.count = 2;
1271     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1272     m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1273 
1274     if(venc_handle->is_secure_session()) {
1275         control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1276         control.value = 1;
1277         DEBUG_PRINT_HIGH("ioctl: open secure device");
1278         ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
1279         if (ret) {
1280             DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
1281             return false;
1282         }
1283     }
1284 
1285     resume_in_stopped = 0;
1286     metadatamode = 0;
1287 
1288     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
1289     control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
1290 
1291     DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
1292 
1293     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1294         DEBUG_PRINT_ERROR("Failed to set control");
1295 
1296     struct v4l2_frmsizeenum frmsize;
1297 
1298     //Get the hardware capabilities
1299     memset((void *)&frmsize,0,sizeof(frmsize));
1300     frmsize.index = 0;
1301     frmsize.pixel_format = m_sVenc_cfg.codectype;
1302     ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1303 
1304     if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1305         DEBUG_PRINT_ERROR("Failed to get framesizes");
1306         return false;
1307     }
1308 
1309     if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1310         capability.min_width = frmsize.stepwise.min_width;
1311         capability.max_width = frmsize.stepwise.max_width;
1312         capability.min_height = frmsize.stepwise.min_height;
1313         capability.max_height = frmsize.stepwise.max_height;
1314     }
1315 
1316     //Initialize non-default parameters
1317     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1318         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
1319         control.value = 0x7fffffff;
1320         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1321             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
1322     }
1323 
1324     property_get("vidc.debug.turbo", property_value, "0");
1325     if (atoi(property_value)) {
1326         DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
1327         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
1328         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
1329         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1330             DEBUG_PRINT_ERROR("Failed to set turbo mode");
1331         }
1332     }
1333     return true;
1334 }
1335 
1336 
unsubscribe_to_events(int fd)1337 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
1338 {
1339     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1340     struct v4l2_event_subscription sub;
1341     int array_sz = sizeof(event_type)/sizeof(int);
1342     int i,rc;
1343 
1344     if (fd < 0) {
1345        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1346         return OMX_ErrorBadParameter;
1347     }
1348 
1349     for (i = 0; i < array_sz; ++i) {
1350         memset(&sub, 0, sizeof(sub));
1351         sub.type = event_type[i];
1352         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1353 
1354         if (rc) {
1355            DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1356             break;
1357         }
1358     }
1359 
1360     return eRet;
1361 }
1362 
venc_close()1363 void venc_dev::venc_close()
1364 {
1365     DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
1366 
1367     if ((int)m_nDriver_fd >= 0) {
1368         DEBUG_PRINT_HIGH("venc_close E");
1369 
1370         if(eventfd_write(m_poll_efd, 1)) {
1371             DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1372             async_thread_force_stop = true;
1373         }
1374 
1375         if (async_thread_created)
1376             pthread_join(m_tid,NULL);
1377 
1378         DEBUG_PRINT_HIGH("venc_close X");
1379         unsubscribe_to_events(m_nDriver_fd);
1380         close(m_poll_efd);
1381         close(m_nDriver_fd);
1382         m_nDriver_fd = -1;
1383     }
1384 
1385     if (m_debug.infile) {
1386         fclose(m_debug.infile);
1387         m_debug.infile = NULL;
1388     }
1389 
1390     if (m_debug.outfile) {
1391         fclose(m_debug.outfile);
1392         m_debug.outfile = NULL;
1393     }
1394 
1395     if (m_debug.extradatafile) {
1396         fclose(m_debug.extradatafile);
1397         m_debug.extradatafile = NULL;
1398     }
1399 
1400     if (m_debug.roiqpfile) {
1401         fclose(m_debug.roiqpfile);
1402         m_debug.roiqpfile = NULL;
1403     }
1404 }
1405 
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1406 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1407         OMX_U32 *actual_buff_count,
1408         OMX_U32 *buff_size,
1409         OMX_U32 port)
1410 {
1411     (void)min_buff_count, (void)buff_size;
1412     unsigned long temp_count = 0;
1413 
1414     if (port == 0) {
1415         if (*actual_buff_count > m_sInput_buff_property.mincount) {
1416             temp_count = m_sInput_buff_property.actualcount;
1417             m_sInput_buff_property.actualcount = *actual_buff_count;
1418             DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1419         }
1420     } else {
1421         if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1422             temp_count = m_sOutput_buff_property.actualcount;
1423             m_sOutput_buff_property.actualcount = *actual_buff_count;
1424             DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1425         }
1426     }
1427 
1428     return true;
1429 
1430 }
1431 
venc_loaded_start()1432 bool venc_dev::venc_loaded_start()
1433 {
1434     return true;
1435 }
1436 
venc_loaded_stop()1437 bool venc_dev::venc_loaded_stop()
1438 {
1439     return true;
1440 }
1441 
venc_loaded_start_done()1442 bool venc_dev::venc_loaded_start_done()
1443 {
1444     return true;
1445 }
1446 
venc_loaded_stop_done()1447 bool venc_dev::venc_loaded_stop_done()
1448 {
1449     return true;
1450 }
1451 
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)1452 bool venc_dev::venc_get_seq_hdr(void *buffer,
1453         unsigned buffer_size, unsigned *header_len)
1454 {
1455     (void) buffer, (void) buffer_size, (void) header_len;
1456     return true;
1457 }
1458 
venc_get_dimensions(OMX_U32 portIndex,OMX_U32 * w,OMX_U32 * h)1459 bool venc_dev::venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h) {
1460     struct v4l2_format fmt;
1461     memset(&fmt, 0, sizeof(fmt));
1462     fmt.type = portIndex == PORT_INDEX_OUT ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
1463             V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1464 
1465     if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
1466         DEBUG_PRINT_ERROR("Failed to get format on %s port",
1467                 portIndex == PORT_INDEX_OUT ? "capture" : "output");
1468         return false;
1469     }
1470     *w = fmt.fmt.pix_mp.width;
1471     *h = fmt.fmt.pix_mp.height;
1472     return true;
1473 }
1474 
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1475 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1476         OMX_U32 *actual_buff_count,
1477         OMX_U32 *buff_size,
1478         OMX_U32 port)
1479 {
1480     struct v4l2_format fmt;
1481     struct v4l2_requestbuffers bufreq;
1482     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1483     int ret;
1484     int extra_idx = 0;
1485 
1486     if (port == 0) {
1487         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1488         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1489         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1490         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1491         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1492         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1493         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1494         bufreq.memory = V4L2_MEMORY_USERPTR;
1495 
1496         if (*actual_buff_count)
1497             bufreq.count = *actual_buff_count;
1498         else
1499             bufreq.count = 2;
1500 
1501         // Increase buffer-header count for metadata-mode on input port
1502         // to improve buffering and reduce bottlenecks in clients
1503         if (metadatamode && (bufreq.count < 9)) {
1504             DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
1505                 bufreq.count);
1506             bufreq.count = 9;
1507         }
1508         if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
1509             DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
1510             bufreq.count = 11;
1511         }
1512 
1513         int actualCount = bufreq.count;
1514         // Request MAX_V4L2_BUFS from V4L2 in batch mode.
1515         // Keep the original count for the client
1516         if (metadatamode && mBatchSize) {
1517             bufreq.count = MAX_V4L2_BUFS;
1518         }
1519 
1520         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1521         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1522 
1523         if (ret) {
1524             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1525             return false;
1526         }
1527         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1528         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1529         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1530         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1531         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1532         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1533 
1534         m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = actualCount;
1535         *min_buff_count = m_sInput_buff_property.mincount;
1536         *actual_buff_count = m_sInput_buff_property.actualcount;
1537 #ifdef USE_ION
1538         // For ION memory allocations of the allocated buffer size
1539         // must be 4k aligned, hence aligning the input buffer
1540         // size to 4k.
1541         m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1542 #endif
1543         *buff_size = m_sInput_buff_property.datasize;
1544         num_input_planes = fmt.fmt.pix_mp.num_planes;
1545         extra_idx = EXTRADATA_IDX(num_input_planes);
1546 
1547         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1548             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1549         } else if (extra_idx >= VIDEO_MAX_PLANES) {
1550             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
1551             return OMX_ErrorBadParameter;
1552         }
1553         mInputExtradata.update(m_sInput_buff_property.actualcount + 1, extra_data_size);
1554     } else {
1555         unsigned int extra_idx = 0;
1556         memset(&fmt, 0, sizeof(fmt));
1557         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1558         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1559         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1560         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1561 
1562         ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1563         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1564         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1565         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1566         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1567         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1568 
1569         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1570         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1571         bufreq.memory = V4L2_MEMORY_USERPTR;
1572 
1573         if (mBatchSize) {
1574             // If we're in batch mode, we'd like to end up in a situation where
1575             // driver is able to own mBatchSize buffers and we'd also own atleast
1576             // mBatchSize buffers
1577             bufreq.count = MAX(*actual_buff_count, mBatchSize) + mBatchSize;
1578         } else if (*actual_buff_count) {
1579             bufreq.count = *actual_buff_count;
1580         } else {
1581             bufreq.count = 2;
1582         }
1583 
1584         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1585         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1586 
1587         if (ret) {
1588             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1589             return false;
1590         }
1591 
1592         m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1593         *min_buff_count = m_sOutput_buff_property.mincount;
1594         *actual_buff_count = m_sOutput_buff_property.actualcount;
1595         *buff_size = m_sOutput_buff_property.datasize;
1596         num_output_planes = fmt.fmt.pix_mp.num_planes;
1597         extra_idx = EXTRADATA_IDX(num_output_planes);
1598 
1599         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1600             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1601         } else if (extra_idx >= VIDEO_MAX_PLANES) {
1602             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1603             return OMX_ErrorBadParameter;
1604         }
1605         mOutputExtradata.update(m_sOutput_buff_property.actualcount, extra_data_size);
1606     }
1607 
1608     return true;
1609 }
1610 
venc_set_param(void * paramData,OMX_INDEXTYPE index)1611 bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index)
1612 {
1613     DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1614     struct v4l2_format fmt;
1615     struct v4l2_requestbuffers bufreq;
1616     int ret;
1617 
1618     switch ((int)index) {
1619         case OMX_IndexParamPortDefinition:
1620             {
1621                 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1622                 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1623                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1624 
1625                 if (portDefn->nPortIndex == PORT_INDEX_IN) {
1626                     if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1627                         return false;
1628                     }
1629 
1630                     if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1631                         return false;
1632                     }
1633                     if (enable_mv_narrow_searchrange &&
1634                         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1635                         (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1636                         if (venc_set_searchrange() == false) {
1637                             DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1638                         }
1639                     }
1640                     if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1641                             m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1642                         DEBUG_PRINT_LOW("Basic parameter has changed");
1643                         m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1644                         m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1645 
1646                         memset(&fmt, 0, sizeof(fmt));
1647                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1648                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1649                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1650                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1651                         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1652 
1653                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1654                             DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1655                             hw_overload = errno == EBUSY;
1656                             return false;
1657                         }
1658 
1659                         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1660                         bufreq.memory = V4L2_MEMORY_USERPTR;
1661                         bufreq.count = portDefn->nBufferCountActual;
1662                         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1663 
1664                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1665                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1666                             return false;
1667                         }
1668 
1669                         if (bufreq.count == portDefn->nBufferCountActual)
1670                             m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1671 
1672                         if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1673                             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1674                     }
1675 
1676                     DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1677                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1678                 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1679                     m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1680                     m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1681 
1682                     memset(&fmt, 0, sizeof(fmt));
1683                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1684                     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1685                     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1686                     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1687 
1688                     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1689                         DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1690                         hw_overload = errno == EBUSY;
1691                         return false;
1692                     }
1693 
1694                     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1695 
1696                     if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1697                         return false;
1698                     }
1699 
1700                         m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1701                         bufreq.memory = V4L2_MEMORY_USERPTR;
1702                         bufreq.count = portDefn->nBufferCountActual;
1703                         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1704 
1705                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1706                             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1707                                     (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1708                             return false;
1709                         }
1710 
1711                         if (bufreq.count == portDefn->nBufferCountActual)
1712                             m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1713 
1714                         if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1715                             m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1716 
1717                     DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1718                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1719                 } else {
1720                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1721                 }
1722 
1723                 break;
1724             }
1725         case OMX_IndexParamVideoPortFormat:
1726             {
1727                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1728                 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1729                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1730 
1731                 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1732                     if (!venc_set_color_format(portFmt->eColorFormat)) {
1733                         return false;
1734                     }
1735                 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1736                     if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1737                         return false;
1738                     }
1739                 } else {
1740                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1741                 }
1742 
1743                 break;
1744             }
1745         case OMX_IndexParamVideoBitrate:
1746             {
1747                 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1748                 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1749                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1750 
1751                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1752                     if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1753                         DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1754                         return false;
1755                     }
1756 
1757                     if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1758                         DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1759                         return false;
1760                     }
1761                 } else {
1762                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1763                 }
1764 
1765                 break;
1766             }
1767         case OMX_IndexParamVideoMpeg4:
1768             {
1769                 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1770                 OMX_U32 bFrames = 0;
1771 
1772                 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1773                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1774 
1775                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1776                     if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1777                         DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1778                         return false;
1779                     }
1780 
1781                     m_profile_set = false;
1782                     m_level_set = false;
1783                     rc_off_level = (int)pParam->eLevel;
1784                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1785                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1786                         return false;
1787                     } else {
1788                         if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1789                             if (pParam->nBFrames) {
1790                                 bFrames = pParam->nBFrames;
1791                             }
1792                         } else {
1793                             if (pParam->nBFrames) {
1794                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1795                                 bFrames = 0;
1796                             }
1797                         }
1798                     }
1799 
1800                     if (!venc_set_intra_period_config (pParam->nPFrames,bFrames)) {
1801                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1802                         return false;
1803                     }
1804 
1805                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1806                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1807                         return false;
1808                     }
1809                 } else {
1810                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1811                 }
1812 
1813                 break;
1814             }
1815         case OMX_IndexParamVideoH263:
1816             {
1817                 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1818                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1819                 OMX_U32 bFrames = 0;
1820 
1821                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1822                     m_profile_set = false;
1823                     m_level_set = false;
1824                     rc_off_level = (int)pParam->eLevel;
1825                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1826                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1827                         return false;
1828                     }
1829 
1830                     if (pParam->nBFrames)
1831                         DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1832 
1833                     if (venc_set_intra_period_config (pParam->nPFrames, bFrames) == false) {
1834                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1835                         return false;
1836                     }
1837                 } else {
1838                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1839                 }
1840 
1841                 break;
1842             }
1843         case OMX_IndexParamVideoAvc:
1844             {
1845                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1846                 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1847                 OMX_U32 bFrames = 0;
1848 
1849                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1850                     DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1851                             pParam->eProfile,pParam->eLevel);
1852 
1853                     m_profile_set = false;
1854                     m_level_set = false;
1855                     rc_off_level = (int)pParam->eLevel;
1856                     if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1857                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1858                                 pParam->eProfile, pParam->eLevel);
1859                         return false;
1860                     } else {
1861                         if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1862                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) OMX_VIDEO_AVCProfileConstrainedBaseline) &&
1863                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1864                             if (pParam->nBFrames) {
1865                                 bFrames = pParam->nBFrames;
1866                             }
1867                         } else {
1868                             if (pParam->nBFrames) {
1869                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1870                                 bFrames = 0;
1871                             }
1872                         }
1873                     }
1874 
1875                     if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) {
1876                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1877                         return false;
1878                     }
1879 
1880                     if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1881                         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1882                         return false;
1883                     }
1884 
1885                     if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1886                         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1887                         return false;
1888                     }
1889 
1890                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1891                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1892                         return false;
1893                     }
1894                 } else {
1895                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1896                 }
1897 
1898                 //TBD, lot of other variables to be updated, yet to decide
1899                 break;
1900             }
1901         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1902             {
1903                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1904                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1905                 rc_off_level = (int)pParam->eLevel;
1906                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1907                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1908                                         pParam->eProfile, pParam->eLevel);
1909                     return false;
1910                 }
1911                 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1912                     DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1913                     return false;
1914                  }
1915                 if(!venc_set_ltrmode(1, 1)) {
1916                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1917                    return false;
1918                 }
1919 
1920                  // For VP8, hier-p and ltr are mutually exclusive features in firmware
1921                  // Disable hier-p if ltr is enabled.
1922                  if (m_codec == OMX_VIDEO_CodingVP8) {
1923                      DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1924                      if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1925                         DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1926                      }
1927                  }
1928 
1929                 break;
1930             }
1931             case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1932             {
1933                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1934                 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1935                 rc_off_level = (int)pParam->eLevel;
1936                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1937                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1938                                         pParam->eProfile, pParam->eLevel);
1939                     return false;
1940                 }
1941                 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1942                     DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1943 
1944                 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1945                 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1946                 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1947                     DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1948                     return false;
1949                 }
1950                 break;
1951             }
1952         case OMX_IndexParamVideoIntraRefresh:
1953             {
1954                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1955                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1956                     (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1957 
1958                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1959                     if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1960                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1961                         return false;
1962                     }
1963                 } else {
1964                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1965                 }
1966 
1967                 break;
1968             }
1969         case OMX_IndexParamVideoErrorCorrection:
1970             {
1971                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1972                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1973                     (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1974 
1975                 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1976                     if (venc_set_error_resilience(error_resilience) == false) {
1977                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1978                         return false;
1979                     }
1980                 } else {
1981                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1982                 }
1983 
1984                 break;
1985             }
1986         case OMX_IndexParamVideoProfileLevelCurrent:
1987             {
1988                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1989                 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1990                     (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1991 
1992                 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1993                     m_profile_set = false;
1994                     m_level_set = false;
1995                     rc_off_level = (int)profile_level->eLevel;
1996                     if (!venc_set_profile_level (profile_level->eProfile,
1997                                 profile_level->eLevel)) {
1998                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1999                         return false;
2000                     }
2001                 } else {
2002                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
2003                 }
2004 
2005                 break;
2006             }
2007         case OMX_IndexParamVideoQuantization:
2008             {
2009                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
2010                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
2011                     (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
2012                 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2013                     if (venc_set_session_qp (session_qp->nQpI,
2014                                 session_qp->nQpP,
2015                                 session_qp->nQpB) == false) {
2016                         DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
2017                         return false;
2018                     }
2019                 } else {
2020                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
2021                 }
2022 
2023                 break;
2024             }
2025         case QOMX_IndexParamVideoInitialQp:
2026             {
2027                 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
2028                     (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
2029                  if (initqp->bEnableInitQp) {
2030                     DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
2031                     if(venc_enable_initial_qp(initqp) == false) {
2032                        DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
2033                        return OMX_ErrorUnsupportedSetting;
2034                      }
2035                  } else
2036                     DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
2037                 break;
2038             }
2039         case OMX_QcomIndexParamVideoQPRange:
2040             {
2041                 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
2042                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
2043                     (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
2044 
2045                 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2046                     if(venc_set_session_qp_range (session_qp_range->minQP,
2047                                 session_qp_range->maxQP) == false) {
2048                         DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
2049                             (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
2050                         return false;
2051                     } else {
2052                         session_qp_values.minqp = session_qp_range->minQP;
2053                         session_qp_values.maxqp = session_qp_range->maxQP;
2054                     }
2055                 } else {
2056                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
2057                 }
2058 
2059                 break;
2060             }
2061         case OMX_QcomIndexEnableSliceDeliveryMode:
2062             {
2063                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
2064                     (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
2065 
2066                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2067                     if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
2068                         DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
2069                         return OMX_ErrorUnsupportedSetting;
2070                     }
2071                 } else {
2072                     DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
2073                             "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
2074                     return OMX_ErrorBadPortIndex;
2075                 }
2076 
2077                 break;
2078             }
2079         case OMX_ExtraDataFrameDimension:
2080             {
2081                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
2082                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2083 
2084                 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
2085                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
2086                     return false;
2087                 }
2088 
2089                 extradata = true;
2090                 break;
2091             }
2092         case OMX_ExtraDataVideoEncoderSliceInfo:
2093             {
2094                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
2095                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2096 
2097                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
2098                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
2099                     return false;
2100                 }
2101 
2102                 extradata = true;
2103                 break;
2104             }
2105         case OMX_ExtraDataVideoEncoderMBInfo:
2106             {
2107                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
2108                 OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
2109 
2110                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
2111                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
2112                     return false;
2113                 }
2114 
2115                 extradata = true;
2116                 break;
2117             }
2118         case OMX_QcomIndexParamSequenceHeaderWithIDR:
2119             {
2120                 PrependSPSPPSToIDRFramesParams * pParam =
2121                     (PrependSPSPPSToIDRFramesParams *)paramData;
2122 
2123                 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
2124                 if(venc_set_inband_video_header(pParam->bEnable) == false) {
2125                     DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
2126                     return OMX_ErrorUnsupportedSetting;
2127                 }
2128 
2129                 break;
2130             }
2131         case OMX_QcomIndexParamH264AUDelimiter:
2132             {
2133                 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
2134                     (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
2135 
2136                 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
2137                 if(venc_set_au_delimiter(pParam->bEnable) == false) {
2138                     DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
2139                     return OMX_ErrorUnsupportedSetting;
2140                 }
2141 
2142                 break;
2143             }
2144         case OMX_QcomIndexParamMBIStatisticsMode:
2145             {
2146                 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
2147                     (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
2148 
2149                 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
2150                 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
2151                     DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
2152                     return OMX_ErrorUnsupportedSetting;
2153                 }
2154 
2155                 break;
2156             }
2157 
2158         case OMX_QcomIndexConfigH264EntropyCodingCabac:
2159             {
2160                 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
2161                     (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
2162 
2163                 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
2164                 if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
2165                     DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
2166                     return OMX_ErrorUnsupportedSetting;
2167                 }
2168 
2169                 break;
2170             }
2171 
2172          case OMX_QcomIndexHierarchicalStructure:
2173            {
2174                QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
2175                    (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
2176 
2177                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2178                     if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
2179                         DEBUG_PRINT_ERROR("Setting Hier P count failed");
2180                         return false;
2181                     }
2182                 } else {
2183                     DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
2184                     return false;
2185                 }
2186 
2187                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
2188                 // Disable ltr if hier-p is enabled.
2189                 if (m_codec == OMX_VIDEO_CodingVP8) {
2190                     DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
2191                     if(!venc_set_ltrmode(0, 1)) {
2192                          DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
2193                      }
2194                 }
2195                 break;
2196            }
2197         case OMX_QcomIndexParamPerfLevel:
2198             {
2199                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
2200                         (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
2201                 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
2202                 if (!venc_set_perf_level(pParam->ePerfLevel)) {
2203                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
2204                     return false;
2205                 } else {
2206                     performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
2207                 }
2208                 break;
2209             }
2210         case OMX_QcomIndexParamH264VUITimingInfo:
2211             {
2212                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
2213                         (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
2214                 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
2215                 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
2216                     DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
2217                     return false;
2218                 } else {
2219                     vui_timing_info.enabled = (unsigned int) pParam->bEnable;
2220                 }
2221                 break;
2222             }
2223         case OMX_QTIIndexParamVQZIPSEIType:
2224             {
2225                 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
2226                         (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
2227                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
2228                 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
2229                     DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
2230                     return false;
2231                 }
2232                 break;
2233             }
2234         case OMX_QcomIndexParamPeakBitrate:
2235             {
2236                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
2237                         (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
2238                 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
2239                 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
2240                     DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
2241                     return false;
2242                 } else {
2243                     peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
2244                 }
2245                 break;
2246             }
2247        case OMX_QcomIndexParamSetMVSearchrange:
2248             {
2249                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
2250                is_searchrange_set = true;
2251                if (!venc_set_searchrange()) {
2252                    DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
2253                    return false;
2254                }
2255             }
2256             break;
2257         case OMX_QcomIndexParamVideoLTRCount:
2258             {
2259                 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
2260                 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
2261                         (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
2262                 if (pParam->nCount > 0) {
2263                     if (venc_set_ltrmode(1, pParam->nCount) == false) {
2264                         DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
2265                         return false;
2266                     }
2267                 } else {
2268                     if (venc_set_ltrmode(0, 0) == false) {
2269                         DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
2270                         return false;
2271                     }
2272                 }
2273                 break;
2274             }
2275         case OMX_QcomIndexParamVideoHybridHierpMode:
2276             {
2277                 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
2278                      DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
2279                      return false;
2280                 }
2281                 break;
2282             }
2283         case OMX_QcomIndexParamBatchSize:
2284             {
2285                 OMX_PARAM_U32TYPE* pParam =
2286                     (OMX_PARAM_U32TYPE*)paramData;
2287 
2288                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2289                     DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
2290                             " on output port");
2291                     return OMX_ErrorUnsupportedSetting;
2292                 }
2293 
2294                 if (!venc_set_batch_size(pParam->nU32)) {
2295                      DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
2296                      return OMX_ErrorUnsupportedSetting;
2297                 }
2298                 break;
2299             }
2300         case OMX_QcomIndexParamVencAspectRatio:
2301             {
2302                 if (!venc_set_aspectratio(paramData)) {
2303                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
2304                     return OMX_ErrorUnsupportedSetting;
2305                 }
2306                 break;
2307             }
2308         case OMX_QTIIndexParamVideoEnableRoiInfo:
2309             {
2310                 struct v4l2_control control;
2311                 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
2312                         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
2313                     DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
2314                     return OMX_ErrorUnsupportedSetting;
2315                 }
2316                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2317                 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
2318                 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
2319                 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2320                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
2321                     return OMX_ErrorUnsupportedSetting;
2322                 }
2323                 break;
2324             }
2325         case OMX_IndexParamAndroidVideoTemporalLayering:
2326             {
2327                 if (venc_set_temporal_layers(
2328                         (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
2329                     DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
2330                     return false;
2331                 }
2332                 break;
2333             }
2334         case OMX_QTIIndexParamEnableAVTimerTimestamps:
2335             {
2336                 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
2337                 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
2338                 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
2339                 break;
2340             }
2341         case OMX_IndexParamVideoSliceFMO:
2342         default:
2343             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
2344                     index);
2345             break;
2346             //case
2347     }
2348 
2349     return true;
2350 }
2351 
venc_check_valid_config()2352 bool venc_dev::venc_check_valid_config()
2353 {
2354    if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
2355        ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
2356        (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
2357         DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
2358         DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
2359         DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
2360         return false;
2361     }
2362    return true;
2363 }
2364 
venc_set_config(void * configData,OMX_INDEXTYPE index)2365 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
2366 {
2367 
2368     DEBUG_PRINT_LOW("Inside venc_set_config");
2369 
2370     if(!venc_check_valid_config()) {
2371         DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
2372         return false;
2373     }
2374 
2375     switch ((int)index) {
2376         case OMX_IndexConfigVideoBitrate:
2377             {
2378                 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
2379                     configData;
2380                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
2381 
2382                 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2383                     if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
2384                         DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
2385                         return false;
2386                     }
2387                 } else {
2388                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
2389                 }
2390 
2391                 break;
2392             }
2393         case OMX_IndexConfigVideoFramerate:
2394             {
2395                 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
2396                     configData;
2397                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
2398 
2399                 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2400                     if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
2401                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2402                         return false;
2403                     }
2404                 } else {
2405                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2406                 }
2407 
2408                 break;
2409             }
2410         case QOMX_IndexConfigVideoIntraperiod:
2411             {
2412                 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
2413                 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
2414                     (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
2415 
2416                 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2417                     if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
2418                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
2419                         return false;
2420                     }
2421                 }
2422 
2423                 break;
2424             }
2425         case OMX_IndexConfigVideoIntraVOPRefresh:
2426             {
2427                 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
2428                     configData;
2429                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
2430 
2431                 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2432                     if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2433                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2434                         return false;
2435                     }
2436                 } else {
2437                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2438                 }
2439 
2440                 break;
2441             }
2442         case OMX_IndexConfigCommonRotate:
2443             {
2444                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2445                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2446                 OMX_U32 nFrameWidth;
2447                 if (!config_rotation) {
2448                    return false;
2449                 }
2450                 if (true == deinterlace_enabled) {
2451                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2452                     return false;
2453                 }
2454                 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2455                 nFrameWidth = m_sVenc_cfg.dvs_width;
2456                 m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
2457                 m_sVenc_cfg.dvs_height = nFrameWidth;
2458 
2459                 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2460                     DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2461                     return false;
2462                 }
2463 
2464                 break;
2465             }
2466         case OMX_IndexConfigVideoAVCIntraPeriod:
2467             {
2468                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2469                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2470 
2471                 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2472                         == false) {
2473                     DEBUG_PRINT_ERROR("ERROR: Setting "
2474                             "OMX_IndexConfigVideoAVCIntraPeriod failed");
2475                     return false;
2476                 }
2477                 break;
2478             }
2479         case OMX_IndexConfigCommonDeinterlace:
2480             {
2481                 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2482                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2483                 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2484                     if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2485                         m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2486                     {
2487                         DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2488                         return false;
2489                     }
2490                     if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2491                         DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2492                         return false;
2493                     }
2494                 } else {
2495                 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2496                 }
2497                 break;
2498             }
2499         case OMX_IndexConfigVideoVp8ReferenceFrame:
2500             {
2501                 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2502                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2503                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2504                         (vp8refframe->bUseGoldenFrame)) {
2505                     if(venc_set_useltr(0x1) == false) {
2506                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2507                         return false;
2508                     }
2509                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2510                         (vp8refframe->bGoldenFrameRefresh)) {
2511                     if(venc_set_markltr(0x1) == false) {
2512                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2513                         return false;
2514                     }
2515                 } else {
2516                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2517                 }
2518                 break;
2519             }
2520         case OMX_QcomIndexConfigVideoLTRUse:
2521             {
2522                 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2523                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2524                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2525                     if (venc_set_useltr(pParam->nID) == false) {
2526                         DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2527                         return false;
2528                     }
2529                 } else {
2530                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2531                 }
2532                 break;
2533             }
2534         case OMX_QcomIndexConfigVideoLTRMark:
2535             {
2536                 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2537                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2538                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2539                     if (venc_set_markltr(pParam->nID) == false) {
2540                         DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2541                         return false;
2542                     }
2543                 }  else {
2544                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2545                 }
2546                 break;
2547             }
2548         case OMX_QcomIndexConfigPerfLevel:
2549             {
2550                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2551                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2552                 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2553                 if (!venc_set_perf_level(perf->ePerfLevel)) {
2554                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2555                     return false;
2556                 } else {
2557                     performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2558                 }
2559                 break;
2560             }
2561         case OMX_QcomIndexConfigVideoVencPerfMode:
2562             {
2563                 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2564                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2565                 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2566                     DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2567                     return false;
2568                 }
2569                 break;
2570             }
2571         case OMX_QcomIndexConfigNumHierPLayers:
2572             {
2573                 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
2574                     (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
2575                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
2576                 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
2577                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
2578                     return false;
2579                 }
2580                 break;
2581             }
2582         case OMX_QcomIndexConfigBaseLayerId:
2583             {
2584                 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
2585                     (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
2586                 if (venc_set_baselayerid(pParam->nPID) == false) {
2587                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
2588                     return OMX_ErrorUnsupportedSetting;
2589                 }
2590                 break;
2591             }
2592         case OMX_IndexParamAndroidVideoTemporalLayering:
2593             {
2594                 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2595                 return false;
2596             }
2597         case OMX_QcomIndexConfigQp:
2598             {
2599                 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
2600                     (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
2601                 if (venc_set_qp(pParam->nQP) == false) {
2602                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
2603                     return OMX_ErrorUnsupportedSetting;
2604                 }
2605                 break;
2606             }
2607         case OMX_IndexConfigPriority:
2608             {
2609                 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2610                 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
2611                 if (!venc_set_priority(priority->nU32)) {
2612                     DEBUG_PRINT_ERROR("Failed to set priority");
2613                     return false;
2614                 }
2615                 sess_priority.priority = priority->nU32;
2616                 break;
2617             }
2618         case OMX_IndexConfigOperatingRate:
2619             {
2620                 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2621                 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2622                 if (!venc_set_operatingrate(rate->nU32)) {
2623                     DEBUG_PRINT_ERROR("Failed to set operating rate");
2624                     return false;
2625                 }
2626                 break;
2627             }
2628         case OMX_QTIIndexConfigVideoRoiInfo:
2629             {
2630                 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
2631                     DEBUG_PRINT_ERROR("Failed to set ROI QP info");
2632                     return false;
2633                 }
2634                 break;
2635             }
2636         case OMX_IndexConfigAndroidIntraRefresh:
2637             {
2638                 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2639                 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2640 
2641                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2642                     OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2643                     OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2644 
2645                     if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2646                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2647                         return false;
2648                     }
2649                 } else {
2650                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2651                 }
2652                 break;
2653             }
2654         case OMX_QTIIndexConfigDescribeColorAspects:
2655             {
2656                 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
2657 
2658                 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
2659                 OMX_U32 full_range = 0;
2660                 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2661                 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2662 
2663                 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
2664                     case ColorAspects::PrimariesBT709_5:
2665                         color_space = MSM_VIDC_BT709_5;
2666                         break;
2667                     case ColorAspects::PrimariesBT470_6M:
2668                         color_space = MSM_VIDC_BT470_6_M;
2669                         break;
2670                     case ColorAspects::PrimariesBT601_6_625:
2671                         color_space = MSM_VIDC_BT601_6_625;
2672                         break;
2673                     case ColorAspects::PrimariesBT601_6_525:
2674                         color_space = MSM_VIDC_BT601_6_525;
2675                         break;
2676                     case ColorAspects::PrimariesGenericFilm:
2677                         color_space = MSM_VIDC_GENERIC_FILM;
2678                         break;
2679                     case ColorAspects::PrimariesBT2020:
2680                         color_space = MSM_VIDC_BT2020;
2681                         break;
2682                     default:
2683                         color_space = MSM_VIDC_BT601_6_625;
2684                         //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2685                         break;
2686                 }
2687                 switch((ColorAspects::Range)params->sAspects.mRange) {
2688                     case ColorAspects::RangeFull:
2689                         full_range = 1;
2690                         break;
2691                     case ColorAspects::RangeLimited:
2692                         full_range = 0;
2693                         break;
2694                     default:
2695                         break;
2696                 }
2697                 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
2698                     case ColorAspects::TransferSMPTE170M:
2699                         transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
2700                         break;
2701                     case ColorAspects::TransferUnspecified:
2702                         transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
2703                         break;
2704                     case ColorAspects::TransferGamma22:
2705                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
2706                         break;
2707                     case ColorAspects::TransferGamma28:
2708                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
2709                         break;
2710                     case ColorAspects::TransferSMPTE240M:
2711                         transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
2712                         break;
2713                     case ColorAspects::TransferLinear:
2714                         transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
2715                         break;
2716                     case ColorAspects::TransferXvYCC:
2717                         transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
2718                         break;
2719                     case ColorAspects::TransferBT1361:
2720                         transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
2721                         break;
2722                     case ColorAspects::TransferSRGB:
2723                         transfer_chars = MSM_VIDC_TRANSFER_SRGB;
2724                         break;
2725                     default:
2726                         //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2727                         transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2728                         break;
2729                 }
2730                 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
2731                     case ColorAspects::MatrixUnspecified:
2732                         matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
2733                         break;
2734                     case ColorAspects::MatrixBT709_5:
2735                         matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
2736                         break;
2737                     case ColorAspects::MatrixBT470_6M:
2738                         matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
2739                         break;
2740                     case ColorAspects::MatrixBT601_6:
2741                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
2742                         break;
2743                     case ColorAspects::MatrixSMPTE240M:
2744                         transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
2745                         break;
2746                     case ColorAspects::MatrixBT2020:
2747                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
2748                         break;
2749                     case ColorAspects::MatrixBT2020Constant:
2750                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
2751                         break;
2752                     default:
2753                         //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2754                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2755                         break;
2756                 }
2757                 if (!venc_set_colorspace(color_space, full_range,
2758                             transfer_chars, matrix_coeffs)) {
2759 
2760                     DEBUG_PRINT_ERROR("Failed to set operating rate");
2761                     return false;
2762                 }
2763                 break;
2764             }
2765         default:
2766             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2767             break;
2768     }
2769 
2770     return true;
2771 }
2772 
venc_stop(void)2773 unsigned venc_dev::venc_stop( void)
2774 {
2775     struct venc_msg venc_msg;
2776     struct v4l2_requestbuffers bufreq;
2777     int rc = 0, ret = 0;
2778 
2779     if (!stopped) {
2780         enum v4l2_buf_type cap_type;
2781 
2782         if (streaming[OUTPUT_PORT]) {
2783             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2784             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2785 
2786             if (rc) {
2787                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2788                         cap_type, rc);
2789             } else
2790                 streaming[OUTPUT_PORT] = false;
2791 
2792             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2793             bufreq.memory = V4L2_MEMORY_USERPTR;
2794             bufreq.count = 0;
2795             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2796             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2797 
2798             if (ret) {
2799                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2800                 return false;
2801             }
2802         }
2803 
2804         if (!rc && streaming[CAPTURE_PORT]) {
2805             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2806             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2807 
2808             if (rc) {
2809                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2810                         cap_type, rc);
2811             } else
2812                 streaming[CAPTURE_PORT] = false;
2813 
2814             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2815             bufreq.memory = V4L2_MEMORY_USERPTR;
2816             bufreq.count = 0;
2817             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2818             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2819 
2820             if (ret) {
2821                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2822                 return false;
2823             }
2824         }
2825 
2826         if (!rc && !ret) {
2827             venc_stop_done();
2828             stopped = 1;
2829             /*set flag to re-configure when started again*/
2830             resume_in_stopped = 1;
2831 
2832         }
2833     }
2834 
2835     return rc;
2836 }
2837 
venc_pause(void)2838 unsigned venc_dev::venc_pause(void)
2839 {
2840     pthread_mutex_lock(&pause_resume_mlock);
2841     paused = true;
2842     pthread_mutex_unlock(&pause_resume_mlock);
2843     return 0;
2844 }
2845 
venc_resume(void)2846 unsigned venc_dev::venc_resume(void)
2847 {
2848     pthread_mutex_lock(&pause_resume_mlock);
2849     paused = false;
2850     pthread_mutex_unlock(&pause_resume_mlock);
2851 
2852     return pthread_cond_signal(&pause_resume_cond);
2853 }
2854 
venc_start_done(void)2855 unsigned venc_dev::venc_start_done(void)
2856 {
2857     struct venc_msg venc_msg;
2858     venc_msg.msgcode = VEN_MSG_START;
2859     venc_msg.statuscode = VEN_S_SUCCESS;
2860     venc_handle->async_message_process(venc_handle,&venc_msg);
2861     return 0;
2862 }
2863 
venc_stop_done(void)2864 unsigned venc_dev::venc_stop_done(void)
2865 {
2866     struct venc_msg venc_msg;
2867     venc_msg.msgcode=VEN_MSG_STOP;
2868     venc_msg.statuscode=VEN_S_SUCCESS;
2869     venc_handle->async_message_process(venc_handle,&venc_msg);
2870     return 0;
2871 }
2872 
venc_set_message_thread_id(pthread_t tid)2873 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2874 {
2875     async_thread_created = true;
2876     m_tid=tid;
2877     return 0;
2878 }
2879 
venc_set_vqzip_defaults()2880 bool venc_dev::venc_set_vqzip_defaults()
2881 {
2882     struct v4l2_control control;
2883     int rc = 0, num_mbs_per_frame;
2884 
2885     num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
2886 
2887     switch (num_mbs_per_frame) {
2888     case OMX_CORE_720P_WIDTH  * OMX_CORE_720P_HEIGHT:
2889     case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
2890     case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
2891     case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
2892         break;
2893     default:
2894         DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
2895             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
2896         return false;
2897     }
2898 
2899     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
2900     control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
2901     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2902     if (rc)
2903         DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
2904     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
2905     control.value = INT_MAX;
2906 
2907     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2908     if (rc)
2909         DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
2910 
2911     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
2912     control.value = 0;
2913 
2914     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2915     if (rc)
2916         DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
2917 
2918     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
2919     control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
2920 
2921     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2922     if (rc)
2923         DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
2924 
2925     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2926     control.value = 1;
2927 
2928     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2929     if (rc)
2930         DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP");
2931 
2932     return true;
2933 }
2934 
2935 
venc_start(void)2936 unsigned venc_dev::venc_start(void)
2937 {
2938     enum v4l2_buf_type buf_type;
2939     int ret, r;
2940     struct v4l2_control control;
2941 
2942     memset(&control, 0, sizeof(control));
2943 
2944     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2945             __func__);
2946     m_level_set = false;
2947 
2948     if (!venc_set_profile_level(0, 0)) {
2949         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2950                 __func__);
2951     } else {
2952         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2953                 __func__, codec_profile.profile, profile_level.level);
2954     }
2955 
2956     if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
2957         return 1;
2958 
2959     // disable B-frames for realtime high-resolution/fps usecases for power considerations
2960     if (intra_period.num_bframes &&
2961             sess_priority.priority == 0 /*realtime*/ &&
2962             (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) ||
2963             (operating_rate >= 60 << 16))) {
2964         intra_period.num_pframes += (intra_period.num_bframes + 1);
2965         intra_period.num_bframes = 0;
2966         if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
2967             DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec",
2968                     m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16);
2969         } else {
2970             DEBUG_PRINT_ERROR("Failed to disable B frames!");
2971         }
2972     }
2973 
2974     // re-configure the temporal layers as RC-mode and key-frame interval
2975     // might have changed since the client last configured the layers.
2976     if (temporal_layers_config.nPLayers) {
2977         if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2978             DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2979         } else {
2980             // request buffers on capture port again since internal (scratch)-
2981             // buffer requirements may change (i.e if we switch from non-hybrid
2982             // to hybrid mode and vice-versa)
2983             struct v4l2_requestbuffers bufreq;
2984 
2985             bufreq.memory = V4L2_MEMORY_USERPTR;
2986             bufreq.count = m_sOutput_buff_property.actualcount;
2987             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2988             if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2989                 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2990             }
2991         }
2992     }
2993 
2994     venc_config_print();
2995 
2996     if(resume_in_stopped){
2997         /*set buffercount when restarted*/
2998         venc_reconfig_reqbufs();
2999         resume_in_stopped = 0;
3000     }
3001 
3002     /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
3003     if (slice_mode.enable && multislice.mslice_size &&
3004             (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
3005         DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
3006                 (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
3007                 MAX_SUPPORTED_SLICES_PER_FRAME);
3008         return 1;
3009     }
3010 
3011     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3012     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
3013     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
3014 
3015     if (ret)
3016         return 1;
3017 
3018     streaming[CAPTURE_PORT] = true;
3019 
3020     control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
3021     control.value = 1;
3022     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3023     if (ret) {
3024         DEBUG_PRINT_ERROR("failed to request seq header");
3025         return 1;
3026     }
3027 
3028 
3029     stopped = 0;
3030     return 0;
3031 }
3032 
hiermode_string(int val)3033 inline const char* hiermode_string(int val)
3034 {
3035     switch(val)
3036     {
3037     case HIER_NONE:
3038         return "No Hier";
3039     case HIER_P:
3040         return "Hier-P";
3041     case HIER_B:
3042         return "Hier-B";
3043     case HIER_P_HYBRID:
3044         return "Hybrid Hier-P";
3045     default:
3046         return "No hier";
3047     }
3048 }
3049 
bitrate_type_string(int val)3050 inline const char* bitrate_type_string(int val)
3051 {
3052     switch(val)
3053     {
3054     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
3055         return "CUMULATIVE";
3056     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
3057         return "LAYER WISE";
3058     default:
3059         return "Unknown Bitrate Type";
3060     }
3061 }
3062 
codec_as_string(unsigned long codec)3063 static const char *codec_as_string(unsigned long codec) {
3064     switch (codec) {
3065     case V4L2_PIX_FMT_H264:
3066         return "H264";
3067     case V4L2_PIX_FMT_MPEG4:
3068         return "MPEG4";
3069     case V4L2_PIX_FMT_H263:
3070         return "H263";
3071     case V4L2_PIX_FMT_HEVC:
3072         return "HEVC";
3073     case V4L2_PIX_FMT_VP8:
3074         return "VP8";
3075     default:
3076         return "UNKOWN";
3077     }
3078 }
3079 
venc_config_print()3080 void venc_dev::venc_config_print()
3081 {
3082 
3083     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
3084             codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
3085 
3086     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
3087             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
3088             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3089 
3090     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
3091             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
3092             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3093 
3094     DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
3095             color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
3096 
3097     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
3098             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
3099 
3100     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
3101             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
3102 
3103     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
3104             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
3105 
3106     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
3107             session_qp_values.minqp, session_qp_values.maxqp);
3108 
3109     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
3110             voptimecfg.voptime_resolution, multislice.mslice_mode,
3111             multislice.mslice_size);
3112 
3113     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
3114             entropy.longentropysel, entropy.cabacmodel);
3115 
3116     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
3117             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
3118             dbkfilter.slicebeta_offset);
3119 
3120     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
3121             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
3122 
3123     DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
3124             ltrinfo.enabled, ltrinfo.count);
3125 
3126     if (temporal_layers_config.nPLayers) {
3127         DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
3128                 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
3129                 intra_period.num_pframes + intra_period.num_bframes + 1);
3130 
3131         for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
3132                 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
3133             DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
3134                     l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
3135         }
3136     } else {
3137 
3138         DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
3139                 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
3140 
3141         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
3142                 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
3143 
3144         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
3145                 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
3146                 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
3147                 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
3148     }
3149 
3150     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
3151 
3152     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
3153 
3154     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
3155 
3156     DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
3157 
3158     DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
3159 }
3160 
venc_reconfig_reqbufs()3161 bool venc_dev::venc_reconfig_reqbufs()
3162 {
3163     struct v4l2_requestbuffers bufreq;
3164 
3165     bufreq.memory = V4L2_MEMORY_USERPTR;
3166     bufreq.count = m_sInput_buff_property.actualcount;
3167     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3168     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3169             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
3170             return false;
3171     }
3172 
3173     bufreq.memory = V4L2_MEMORY_USERPTR;
3174     bufreq.count = m_sOutput_buff_property.actualcount;
3175     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3176     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
3177     {
3178             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
3179             return false;
3180     }
3181     return true;
3182 }
3183 
venc_flush(unsigned port)3184 unsigned venc_dev::venc_flush( unsigned port)
3185 {
3186     struct v4l2_encoder_cmd enc;
3187     DEBUG_PRINT_LOW("in %s", __func__);
3188 
3189     enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
3190     enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3191 
3192     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
3193         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
3194         return -1;
3195     }
3196 
3197     return 0;
3198 
3199 }
3200 
3201 //allocating I/P memory from pmem and register with the device
3202 
3203 
venc_use_buf(void * buf_addr,unsigned port,unsigned index)3204 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
3205 {
3206 
3207     struct pmem *pmem_tmp;
3208     struct v4l2_buffer buf;
3209     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3210     int rc = 0;
3211     unsigned int extra_idx;
3212 
3213     pmem_tmp = (struct pmem *)buf_addr;
3214     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
3215 
3216     if (port == PORT_INDEX_OUT) {
3217         extra_idx = EXTRADATA_IDX(num_output_planes);
3218         buf.index = index;
3219         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3220         buf.memory = V4L2_MEMORY_USERPTR;
3221         plane[0].length = pmem_tmp->size;
3222         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
3223         plane[0].reserved[0] = pmem_tmp->fd;
3224         plane[0].reserved[1] = 0;
3225         plane[0].data_offset = pmem_tmp->offset;
3226         buf.m.planes = plane;
3227         buf.length = num_output_planes;
3228 
3229         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3230             char *userptr;
3231             int fd;
3232             unsigned offset;
3233             ssize_t size;
3234             int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size);
3235             if (rc != OMX_ErrorNone) {
3236                 DEBUG_PRINT_ERROR("Unable to get extradata memory 2");
3237                 return rc;
3238             }
3239             plane[extra_idx].length = size;
3240             plane[extra_idx].m.userptr = (unsigned long)userptr;
3241 #ifdef USE_ION
3242             plane[extra_idx].reserved[0] = fd;
3243 #endif
3244             plane[extra_idx].reserved[1] = offset;
3245             plane[extra_idx].data_offset = 0;
3246         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
3247             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
3248             return OMX_ErrorBadParameter;
3249         }
3250 
3251         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
3252 
3253         if (rc)
3254             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
3255     } else if (port == PORT_INDEX_IN) {
3256             DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port");
3257     } else {
3258         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
3259         return false;
3260     }
3261 
3262     return true;
3263 }
3264 
venc_free_buf(void * buf_addr,unsigned port)3265 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
3266 {
3267     struct pmem *pmem_tmp;
3268     struct venc_bufferpayload dev_buffer;
3269 
3270     memset(&dev_buffer, 0, sizeof(dev_buffer));
3271     pmem_tmp = (struct pmem *)buf_addr;
3272 
3273     if (port == PORT_INDEX_IN) {
3274         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3275         dev_buffer.fd  = pmem_tmp->fd;
3276         dev_buffer.maped_size = pmem_tmp->size;
3277         dev_buffer.sz = pmem_tmp->size;
3278         dev_buffer.offset = pmem_tmp->offset;
3279         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3280                 dev_buffer.pbuffer, \
3281                 dev_buffer.fd, \
3282                 dev_buffer.offset, \
3283                 dev_buffer.maped_size);
3284 
3285     } else if (port == PORT_INDEX_OUT) {
3286         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3287         dev_buffer.fd  = pmem_tmp->fd;
3288         dev_buffer.sz = pmem_tmp->size;
3289         dev_buffer.maped_size = pmem_tmp->size;
3290         dev_buffer.offset = pmem_tmp->offset;
3291 
3292         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3293                 dev_buffer.pbuffer, \
3294                 dev_buffer.fd, \
3295                 dev_buffer.offset, \
3296                 dev_buffer.maped_size);
3297     } else {
3298         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
3299         return false;
3300     }
3301 
3302     return true;
3303 }
3304 
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3305 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
3306         OMX_U32 width, OMX_U32 height)
3307 {
3308     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
3309             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
3310             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
3311             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
3312             src_chroma_offset = width * height;
3313 
3314     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
3315         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3316         //Do chroma first, so that we can convert it in-place
3317         src_buf += width * height;
3318         dst_buf += y_stride * y_scanlines;
3319         for (int line = height / 2 - 1; line >= 0; --line) {
3320             memmove(dst_buf + line * uv_stride,
3321                     src_buf + line * width,
3322                     width);
3323         }
3324 
3325         dst_buf = src_buf = buffer->pBuffer;
3326         //Copy the Y next
3327         for (int line = height - 1; line > 0; --line) {
3328             memmove(dst_buf + line * y_stride,
3329                     src_buf + line * width,
3330                     width);
3331         }
3332     } else {
3333         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3334                 Insufficient bufferLen=%u v/s Required=%u",
3335                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3336                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3337         return false;
3338     }
3339 
3340     return true;
3341 }
3342 
venc_get_performance_level(OMX_U32 * perflevel)3343 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
3344 {
3345     if (!perflevel) {
3346         DEBUG_PRINT_ERROR("Null pointer error");
3347         return false;
3348     } else {
3349         *perflevel = performance_level.perflevel;
3350         return true;
3351     }
3352 }
3353 
venc_get_vui_timing_info(OMX_U32 * enabled)3354 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
3355 {
3356     if (!enabled) {
3357         DEBUG_PRINT_ERROR("Null pointer error");
3358         return false;
3359     } else {
3360         *enabled = vui_timing_info.enabled;
3361         return true;
3362     }
3363 }
3364 
venc_get_vqzip_sei_info(OMX_U32 * enabled)3365 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
3366 {
3367     if (!enabled) {
3368         DEBUG_PRINT_ERROR("Null pointer error");
3369         return false;
3370     } else {
3371         *enabled = vqzip_sei_info.enabled;
3372         return true;
3373     }
3374 }
3375 
venc_get_peak_bitrate(OMX_U32 * peakbitrate)3376 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
3377 {
3378     if (!peakbitrate) {
3379         DEBUG_PRINT_ERROR("Null pointer error");
3380         return false;
3381     } else {
3382         *peakbitrate = peak_bitrate.peakbitrate;
3383         return true;
3384     }
3385 }
3386 
venc_get_batch_size(OMX_U32 * size)3387 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
3388 {
3389     if (!size) {
3390         DEBUG_PRINT_ERROR("Null pointer error");
3391         return false;
3392     } else {
3393         *size = mBatchSize;
3394         return true;
3395     }
3396 }
3397 
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3398 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
3399 {
3400     struct pmem *temp_buffer;
3401     struct v4l2_buffer buf;
3402     struct v4l2_requestbuffers bufreq;
3403     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3404     int rc = 0, extra_idx;
3405     struct OMX_BUFFERHEADERTYPE *bufhdr;
3406     encoder_media_buffer_type * meta_buf = NULL;
3407     temp_buffer = (struct pmem *)buffer;
3408 
3409     memset (&buf, 0, sizeof(buf));
3410     memset (&plane, 0, sizeof(plane));
3411 
3412     if (buffer == NULL) {
3413         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
3414         return false;
3415     }
3416 
3417     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3418     bufreq.memory = V4L2_MEMORY_USERPTR;
3419     bufreq.count = m_sInput_buff_property.actualcount;
3420     bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3421 
3422     DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
3423 
3424     if (pmem_data_buf) {
3425         DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
3426         plane[0].m.userptr = (unsigned long)pmem_data_buf;
3427         plane[0].data_offset = bufhdr->nOffset;
3428         plane[0].length = bufhdr->nAllocLen;
3429         plane[0].bytesused = bufhdr->nFilledLen;
3430     } else {
3431         // --------------------------------------------------------------------------------------
3432         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
3433         // ---------------------------------------------------------------------------------------
3434         // Camera-2              1            CameraSource   0              meta-handle
3435         // Camera-3              1            GrallocSource  0              gralloc-private-handle
3436         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
3437         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
3438         // ---------------------------------------------------------------------------------------
3439         if (metadatamode) {
3440             plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3441             meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3442 
3443             if (!meta_buf) {
3444                 //empty EOS buffer
3445                 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
3446                     plane[0].data_offset = bufhdr->nOffset;
3447                     plane[0].length = bufhdr->nAllocLen;
3448                     plane[0].bytesused = bufhdr->nFilledLen;
3449                     DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
3450                 } else {
3451                     return false;
3452                 }
3453             } else if (!color_format) {
3454                 int usage = 0;
3455 
3456                 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3457                     native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
3458                     if (!hnd) {
3459                         DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
3460                         return false;
3461                     }
3462 
3463                     if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
3464                         usage = hnd->data[3];
3465                     } else if (mBatchSize) {
3466                         usage = BatchInfo::getColorFormatAt(hnd, 0);
3467                     }
3468                     if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
3469                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3470                     }
3471 
3472                     if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
3473                         m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
3474                         struct v4l2_format fmt;
3475 
3476                         memset(&fmt, 0, sizeof(fmt));
3477                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
3478                                 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
3479                             DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
3480                             DEBUG_PRINT_ERROR(" This leads to unknown color space");
3481                         }
3482                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
3483                             if (is_csc_enabled) {
3484                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3485                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3486                                 venc_set_colorspace(MSM_VIDC_BT709_5, 1,
3487                                         MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
3488                             } else {
3489                                 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
3490                                         MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3491                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3492                             }
3493                         }
3494                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3495                         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3496                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3497                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3498                         if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
3499                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
3500                         }
3501                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3502                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3503                             DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
3504                             return false;
3505                         }
3506                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3507                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3508                             return false;
3509                         }
3510                     }
3511 
3512                     // Setting batch mode is sticky. We do not expect camera to change
3513                     // between batch and normal modes at runtime.
3514                     if (mBatchSize) {
3515                         if ((unsigned)hnd->numFds != mBatchSize) {
3516                             DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
3517                                     mBatchSize, hnd->numFds);
3518                             return false;
3519                         }
3520 
3521                         return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
3522                     }
3523 
3524                     if (hnd->numFds + hnd->numInts > 2) {
3525                         plane[0].data_offset = hnd->data[1];
3526                         plane[0].length = hnd->data[2];
3527                         plane[0].bytesused = hnd->data[2];
3528                     }
3529                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
3530                             fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
3531                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
3532                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
3533 
3534                     if (!handle) {
3535                         DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
3536                         return false;
3537                     }
3538 
3539                     if (mUseAVTimerTimestamps) {
3540                         uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
3541                         if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
3542                                 && avTimerTimestampNs > 0) {
3543                             bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
3544                             DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
3545                         }
3546                     }
3547 
3548                     if (!streaming[OUTPUT_PORT]) {
3549                         // Moment of truth... actual colorspace is known here..
3550                         ColorSpace_t colorSpace = ITU_R_601;
3551                         if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
3552                             DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3553                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3554                         }
3555 
3556                         struct v4l2_format fmt;
3557                         memset(&fmt, 0, sizeof(fmt));
3558                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3559 
3560                         bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
3561                         if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3562                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
3563                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
3564                         } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
3565                             // In case of RGB, conversion to YUV is handled within encoder.
3566                             // Disregard the Colorspace in gralloc-handle in case of RGB and use
3567                             //   [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
3568                             //   [b] 601 for UBWC case     : Venus can convert to 601-LR or FR. use LR for now.
3569                             colorSpace = ITU_R_601;
3570                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
3571                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
3572                         } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3573                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3574                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
3575                         }
3576 
3577                         // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
3578                         if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
3579                             struct v4l2_control control;
3580                             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
3581                             control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
3582                             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3583                                 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
3584                             } else {
3585                                 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
3586                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3587                                 colorSpace = ITU_R_709;
3588                             }
3589                         }
3590 
3591                         msm_vidc_h264_color_primaries_values primary;
3592                         msm_vidc_h264_transfer_chars_values transfer;
3593                         msm_vidc_h264_matrix_coeff_values matrix;
3594                         OMX_U32 range;
3595 
3596                         switch (colorSpace) {
3597                             case ITU_R_601_FR:
3598                             {
3599                                 primary = MSM_VIDC_BT601_6_525;
3600                                 range = 1; // full
3601                                 transfer = MSM_VIDC_TRANSFER_601_6_525;
3602                                 matrix = MSM_VIDC_MATRIX_601_6_525;
3603 
3604                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3605                                 break;
3606                             }
3607                             case ITU_R_709:
3608                             {
3609                                 primary = MSM_VIDC_BT709_5;
3610                                 range = 0; // limited
3611                                 transfer = MSM_VIDC_TRANSFER_BT709_5;
3612                                 matrix = MSM_VIDC_MATRIX_BT_709_5;
3613 
3614                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3615                                 break;
3616                             }
3617                             default:
3618                             {
3619                                 // 601 or something else ? assume 601
3620                                 primary = MSM_VIDC_BT601_6_625;
3621                                 range = 0; //limited
3622                                 transfer = MSM_VIDC_TRANSFER_601_6_625;
3623                                 matrix = MSM_VIDC_MATRIX_601_6_625;
3624 
3625                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3626                                 break;
3627                             }
3628                         }
3629                         DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3630                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3631                         venc_set_colorspace(primary, range, transfer, matrix);
3632 
3633                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3634                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3635                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3636                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3637                             DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
3638                             return false;
3639                         }
3640                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3641                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3642                             return false;
3643                         }
3644                     }
3645 
3646                     fd = handle->fd;
3647                     plane[0].data_offset = 0;
3648                     plane[0].length = handle->size;
3649                     plane[0].bytesused = handle->size;
3650                     DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
3651                                 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
3652                 }
3653             } else {
3654                 // color_format == 1 ==> RGBA to YUV Color-converted buffer
3655                 // Buffers color-converted via C2D have 601-Limited color
3656                 if (!streaming[OUTPUT_PORT]) {
3657                     DEBUG_PRINT_HIGH("Setting colorspace 601-L for Color-converted buffer");
3658                     venc_set_colorspace(MSM_VIDC_BT601_6_625, 0 /*range-limited*/,
3659                             MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3660                 }
3661                 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3662                 plane[0].data_offset = bufhdr->nOffset;
3663                 plane[0].length = bufhdr->nAllocLen;
3664                 plane[0].bytesused = bufhdr->nFilledLen;
3665                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
3666                         fd, plane[0].bytesused, plane[0].length);
3667             }
3668         } else {
3669             plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3670             plane[0].data_offset = bufhdr->nOffset;
3671             plane[0].length = bufhdr->nAllocLen;
3672             plane[0].bytesused = bufhdr->nFilledLen;
3673             DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
3674                     fd, plane[0].bytesused, plane[0].length);
3675         }
3676     }
3677 
3678     extra_idx = EXTRADATA_IDX(num_input_planes);
3679 
3680     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3681         char *userptr;
3682         int fd;
3683         unsigned offset;
3684         ssize_t size;
3685         int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
3686         if (rc != OMX_ErrorNone) {
3687             DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
3688             return rc;
3689         }
3690         plane[extra_idx].bytesused = 0;
3691         plane[extra_idx].length = size;
3692         plane[extra_idx].m.userptr = (unsigned long) userptr;
3693 #ifdef USE_ION
3694         plane[extra_idx].reserved[0] = fd;
3695 #endif
3696         plane[extra_idx].reserved[1] = offset;
3697         plane[extra_idx].data_offset = 0;
3698     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3699         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3700         return false;
3701     }
3702 
3703     if (!streaming[OUTPUT_PORT]) {
3704         enum v4l2_buf_type buf_type;
3705         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3706         int ret;
3707         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3708 
3709         if (ret) {
3710             DEBUG_PRINT_ERROR("Failed to call streamon");
3711             if (errno == EBUSY) {
3712                 hw_overload = true;
3713             }
3714             return false;
3715         } else {
3716             streaming[OUTPUT_PORT] = true;
3717         }
3718     }
3719 
3720     buf.index = index;
3721     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3722     buf.memory = V4L2_MEMORY_USERPTR;
3723     plane[0].reserved[0] = fd;
3724     plane[0].reserved[1] = 0;
3725     buf.m.planes = plane;
3726     buf.length = num_input_planes;
3727 
3728     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3729         buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3730 
3731     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3732     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3733     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3734 
3735     if (rc) {
3736         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3737         return false;
3738     }
3739 
3740     etb++;
3741 
3742     if (m_debug.in_buffer_log) {
3743         venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
3744     }
3745 
3746     return true;
3747 }
3748 
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3749 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3750 {
3751     struct v4l2_buffer buf;
3752     struct v4l2_plane plane;
3753     int rc = 0;
3754     struct v4l2_control control;
3755     encoder_media_buffer_type * meta_buf = NULL;
3756     native_handle_t *hnd = NULL;
3757 
3758     if (bufhdr == NULL) {
3759         DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3760         return false;
3761     }
3762 
3763     bool status = true;
3764     if (metadatamode) {
3765         plane.m.userptr = (unsigned long)bufhdr->pBuffer;
3766         meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3767 
3768         if (!color_format) {
3769             if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3770                 hnd = (native_handle_t*)meta_buf->meta_handle;
3771                 if (!hnd) {
3772                     DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3773                     return false;
3774                 } else if (hnd->numFds > kMaxBuffersInBatch) {
3775                     DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3776                             "Max = %d", hnd->numFds, kMaxBuffersInBatch);
3777                     status = false;
3778                 }
3779                 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
3780             } else {
3781                 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3782                 status = false;
3783             }
3784         } else {
3785             DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3786             status = false;
3787         }
3788     } else {
3789         DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3790         status = false;
3791     }
3792 
3793     if (status) {
3794         OMX_TICKS bufTimeStamp = 0ll;
3795         int numBufs = hnd->numFds;
3796         int v4l2Ids[kMaxBuffersInBatch] = {-1};
3797         for (int i = 0; i < numBufs; ++i) {
3798             v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3799             if (v4l2Ids[i] < 0) {
3800                 DEBUG_PRINT_ERROR("Failed to register buffer");
3801                 // TODO: cleanup the map and purge all slots of current index
3802                 status = false;
3803                 break;
3804             }
3805         }
3806         for (int i = 0; i < numBufs; ++i) {
3807             int v4l2Id = v4l2Ids[i];
3808 
3809             memset(&buf, 0, sizeof(buf));
3810             memset(&plane, 0, sizeof(plane));
3811 
3812             DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3813             buf.index = (unsigned)v4l2Id;
3814             buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3815             buf.memory = V4L2_MEMORY_USERPTR;
3816             plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
3817             plane.reserved[1] = 0;
3818             plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
3819             plane.m.userptr = (unsigned long)meta_buf;
3820             plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
3821             buf.m.planes = &plane;
3822             buf.length = 1;
3823 
3824             if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3825                 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3826             if (i != numBufs - 1) {
3827                 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3828                 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
3829                         i, etb + 1, numBufs);
3830             }
3831 
3832 
3833             // timestamp differences from camera are in nano-seconds
3834             bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
3835 
3836             DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3837                 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
3838             buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3839             buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3840 
3841             rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3842             if (rc) {
3843                 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3844                 return false;
3845             }
3846 
3847             etb++;
3848         }
3849     }
3850 
3851     if (status && !streaming[OUTPUT_PORT]) {
3852         enum v4l2_buf_type buf_type;
3853         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3854         int ret;
3855         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3856         if (ret) {
3857             DEBUG_PRINT_ERROR("Failed to call streamon");
3858             if (errno == EBUSY) {
3859                 hw_overload = true;
3860             }
3861             status = false;
3862         } else {
3863             streaming[OUTPUT_PORT] = true;
3864         }
3865     }
3866 
3867     return status;
3868 }
3869 
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3870 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3871 {
3872     struct pmem *temp_buffer = NULL;
3873     struct venc_buffer  frameinfo;
3874     struct v4l2_buffer buf;
3875     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3876     int rc = 0;
3877     unsigned int extra_idx;
3878     struct OMX_BUFFERHEADERTYPE *bufhdr;
3879 
3880     if (buffer == NULL)
3881         return false;
3882 
3883     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3884 
3885     if (pmem_data_buf) {
3886         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3887         plane[0].m.userptr = (unsigned long)pmem_data_buf;
3888     } else {
3889         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3890         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3891     }
3892 
3893     memset(&buf, 0, sizeof(buf));
3894     memset(&plane, 0, sizeof(plane));
3895 
3896     buf.index = index;
3897     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3898     buf.memory = V4L2_MEMORY_USERPTR;
3899     plane[0].length = bufhdr->nAllocLen;
3900     plane[0].bytesused = bufhdr->nFilledLen;
3901     plane[0].reserved[0] = fd;
3902     plane[0].reserved[1] = 0;
3903     plane[0].data_offset = bufhdr->nOffset;
3904     buf.m.planes = plane;
3905     buf.length = num_output_planes;
3906     buf.flags = 0;
3907 
3908     if (mBatchSize) {
3909         // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
3910         // This results in the first batch being of size mBatchSize + 1, but thats good because
3911         // we need an extra FTB for the codec specific data.
3912 
3913         if (!ftb || ftb % mBatchSize) {
3914             buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3915             DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
3916         }
3917     }
3918 
3919     extra_idx = EXTRADATA_IDX(num_output_planes);
3920 
3921     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3922         char *userptr;
3923         int fd;
3924         unsigned offset;
3925         ssize_t size;
3926         int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
3927         if (rc != OMX_ErrorNone) {
3928             DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
3929             return false;
3930         }
3931         plane[extra_idx].bytesused = 0;
3932         plane[extra_idx].length = size;
3933         plane[extra_idx].m.userptr = (unsigned long)userptr;
3934 #ifdef USE_ION
3935         plane[extra_idx].reserved[0] = fd;
3936 #endif
3937         plane[extra_idx].reserved[1] = offset;
3938         plane[extra_idx].data_offset = 0;
3939     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3940         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3941         return false;
3942     }
3943 
3944     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3945 
3946     if (rc) {
3947         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3948         return false;
3949     }
3950 
3951     ftb++;
3952     return true;
3953 }
3954 
venc_set_inband_video_header(OMX_BOOL enable)3955 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
3956 {
3957     struct v4l2_control control;
3958 
3959     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
3960     if(enable) {
3961         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
3962     } else {
3963         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
3964     }
3965 
3966     DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
3967     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3968         DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
3969         return false;
3970     }
3971     return true;
3972 }
3973 
venc_set_au_delimiter(OMX_BOOL enable)3974 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
3975 {
3976     struct v4l2_control control;
3977 
3978     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
3979     if(enable) {
3980         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
3981     } else {
3982         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
3983     }
3984 
3985     DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
3986     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3987         DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
3988         return false;
3989     }
3990     return true;
3991 }
3992 
venc_set_mbi_statistics_mode(OMX_U32 mode)3993 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
3994 {
3995     struct v4l2_control control;
3996 
3997     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
3998     control.value = mode;
3999 
4000     DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
4001     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
4002         DEBUG_PRINT_ERROR("Setting MBI mode failed");
4003         return false;
4004     }
4005     return true;
4006 }
4007 
venc_set_vqzip_sei_type(OMX_BOOL enable)4008 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
4009 {
4010     struct v4l2_control sei_control, yuvstats_control;
4011 
4012     DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
4013     sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
4014     yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4015 
4016     if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
4017         DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
4018     }
4019 
4020     if(enable) {
4021         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
4022         yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4023     } else {
4024         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
4025         yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4026     }
4027 
4028     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
4029         DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
4030     }
4031 
4032     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
4033         DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
4034     }
4035 #ifdef _VQZIP_
4036     vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
4037     vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
4038     vqzip.init();
4039     vqzip_sei_info.enabled = true;
4040 #endif
4041 
4042     return true;
4043 }
4044 
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)4045 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
4046 {
4047     // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
4048     if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
4049         return false;
4050 
4051     // Check for bframes with Hier-P-Hybrid
4052     if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
4053         return false;
4054 
4055     // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
4056     if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
4057            hier_layers.hier_mode == HIER_B || ltrinfo.count))
4058         return false;
4059 
4060     // Check for LTR with Hier-P-Hybrid
4061     if (count && hier_layers.hier_mode == HIER_P_HYBRID)
4062         return false;
4063 
4064     return true;
4065 }
4066 
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)4067 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
4068                                     OMX_U32 num_layers)
4069 {
4070     struct v4l2_control control;
4071 
4072     if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
4073         DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
4074         return false;
4075     }
4076 
4077     if (type == QOMX_HIERARCHICALCODING_P) {
4078         // Reduce layer count by 1 before sending to driver. This avoids
4079         // driver doing the same in multiple places.
4080         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
4081         control.value = num_layers - 1;
4082         DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
4083         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4084             DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
4085             return false;
4086         }
4087         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
4088         control.value = num_layers - 1;
4089         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
4090         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4091             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4092             return false;
4093         }
4094         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4095             DEBUG_PRINT_LOW("Set H264_SVC_NAL");
4096             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4097             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4098             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4099                 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4100                 return false;
4101             }
4102         }
4103         hier_layers.hier_mode = HIER_P;
4104     } else if (type == QOMX_HIERARCHICALCODING_B) {
4105         if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4106             DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
4107             return false;
4108         }
4109         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
4110         control.value = num_layers - 1;
4111         DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
4112         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4113             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4114             return false;
4115         }
4116         hier_layers.hier_mode = HIER_B;
4117     } else {
4118         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
4119         return false;
4120     }
4121     hier_layers.numlayers = num_layers;
4122     return true;
4123 }
4124 
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)4125 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
4126 {
4127     struct v4l2_control control;
4128 
4129     DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
4130 
4131     if (enable == OMX_FALSE) {
4132         /* No easy way to turn off extradata to the driver
4133          * at the moment */
4134         return false;
4135     }
4136 
4137     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4138     switch (extra_data) {
4139         case OMX_ExtraDataVideoEncoderSliceInfo:
4140             control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
4141             break;
4142         case OMX_ExtraDataVideoEncoderMBInfo:
4143             control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
4144             break;
4145         case OMX_ExtraDataFrameDimension:
4146             control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
4147             break;
4148         default:
4149             DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
4150             return false;
4151     }
4152 
4153     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4154         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
4155                 (unsigned int)extra_data, errno);
4156         return false;
4157     }
4158 
4159     return true;
4160 }
4161 
venc_set_slice_delivery_mode(OMX_U32 enable)4162 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
4163 {
4164     struct v4l2_control control;
4165 
4166     if (enable) {
4167         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
4168         control.value = 1;
4169         DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
4170 
4171         if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4172             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4173                 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
4174                 return false;
4175             } else {
4176                 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
4177                 slice_mode.enable = 1;
4178             }
4179         } else {
4180             DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
4181                     "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
4182                     m_sVenc_cfg.codectype);
4183         }
4184     } else {
4185         DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
4186     }
4187 
4188     return true;
4189 }
4190 
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)4191 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
4192 {
4193     int rc;
4194     struct v4l2_control control;
4195     struct v4l2_ext_control ctrl[4];
4196     struct v4l2_ext_controls controls;
4197 
4198     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
4199     ctrl[0].value = initqp->nQpI;
4200     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
4201     ctrl[1].value = initqp->nQpP;
4202     ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
4203     ctrl[2].value = initqp->nQpB;
4204     ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
4205     ctrl[3].value = initqp->bEnableInitQp;
4206 
4207     controls.count = 4;
4208     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4209     controls.controls = ctrl;
4210 
4211     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4212                     controls.controls[0].id, controls.controls[0].value,
4213                     controls.controls[1].id, controls.controls[1].value,
4214                     controls.controls[2].id, controls.controls[2].value,
4215                     controls.controls[3].id, controls.controls[3].value);
4216 
4217     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4218     if (rc) {
4219         DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
4220         return false;
4221     }
4222 
4223     init_qp.iframeqp = initqp->nQpI;
4224     init_qp.pframeqp = initqp->nQpP;
4225     init_qp.bframeqp = initqp->nQpB;
4226     init_qp.enableinitqp = initqp->bEnableInitQp;
4227 
4228     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4229                     controls.controls[0].id, controls.controls[0].value,
4230                     controls.controls[1].id, controls.controls[1].value,
4231                     controls.controls[2].id, controls.controls[2].value,
4232                     controls.controls[3].id, controls.controls[3].value);
4233     return true;
4234 }
4235 
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)4236 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
4237     OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
4238 {
4239     int rc;
4240     struct v4l2_control control;
4241 
4242     DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
4243         primaries, range, transfer_chars, matrix_coeffs);
4244 
4245     control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
4246     control.value = primaries;
4247 
4248     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4249     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4250 
4251     if (rc) {
4252         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
4253         return false;
4254     }
4255 
4256     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4257 
4258     color_space.primaries = control.value;
4259 
4260     control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
4261     control.value = range;
4262 
4263     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4264     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4265 
4266     if (rc) {
4267         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
4268         return false;
4269     }
4270 
4271     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4272 
4273     color_space.range = control.value;
4274 
4275     control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
4276     control.value = transfer_chars;
4277 
4278     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4279     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4280 
4281     if (rc) {
4282         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
4283         return false;
4284     }
4285 
4286     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4287 
4288     color_space.transfer_chars = control.value;
4289 
4290     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
4291     control.value = matrix_coeffs;
4292 
4293     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4294     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4295 
4296     if (rc) {
4297         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
4298         return false;
4299     }
4300 
4301     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4302 
4303     color_space.matrix_coeffs = control.value;
4304 
4305     return true;
4306 }
4307 
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)4308 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
4309 {
4310     int rc;
4311     struct v4l2_control control;
4312 
4313     control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
4314     control.value = i_frame_qp;
4315 
4316     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4317     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4318 
4319     if (rc) {
4320         DEBUG_PRINT_ERROR("Failed to set control");
4321         return false;
4322     }
4323 
4324     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4325     session_qp.iframeqp = control.value;
4326 
4327     control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
4328     control.value = p_frame_qp;
4329 
4330     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4331     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4332 
4333     if (rc) {
4334         DEBUG_PRINT_ERROR("Failed to set control");
4335         return false;
4336     }
4337 
4338     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4339 
4340     session_qp.pframeqp = control.value;
4341 
4342     if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
4343             (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4344 
4345         control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
4346         control.value = b_frame_qp;
4347 
4348         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4349         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4350 
4351         if (rc) {
4352             DEBUG_PRINT_ERROR("Failed to set control");
4353             return false;
4354         }
4355 
4356         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4357 
4358         session_qp.bframeqp = control.value;
4359     }
4360 
4361     return true;
4362 }
4363 
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)4364 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
4365 {
4366     int rc;
4367     struct v4l2_control control;
4368 
4369     if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
4370 
4371         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4372             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
4373         else
4374             control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
4375         control.value = min_qp;
4376 
4377         DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
4378                 control.id, control.value);
4379         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4380         if (rc) {
4381             DEBUG_PRINT_ERROR("Failed to set control");
4382             return false;
4383         }
4384 
4385         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4386             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
4387         else
4388             control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
4389         control.value = max_qp;
4390 
4391         DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
4392                 control.id, control.value);
4393         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4394         if (rc) {
4395             DEBUG_PRINT_ERROR("Failed to set control");
4396             return false;
4397         }
4398     } else {
4399         DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
4400             (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
4401     }
4402 
4403     return true;
4404 }
4405 
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)4406 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
4407 {
4408     struct venc_profile requested_profile = {0};
4409     struct ven_profilelevel requested_level = {0};
4410     unsigned long mb_per_frame = 0;
4411     DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
4412             (unsigned int)eProfile, (unsigned int)eLevel);
4413     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4414         ((m_sVenc_cfg.dvs_width + 15) >> 4);
4415 
4416     if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
4417         DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
4418         return true;
4419     }
4420 
4421     if (vqzip_sei_info.enabled) {
4422         DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
4423         return true;
4424     }
4425 
4426     DEBUG_PRINT_LOW("Validating Profile/Level from table");
4427 
4428     if (!venc_validate_profile_level(&eProfile, &eLevel)) {
4429         DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
4430         return false;
4431     }
4432 
4433     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4434         DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
4435                 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
4436                 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
4437 
4438         if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4439             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
4440         } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4441             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
4442         } else {
4443             DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
4444                     (unsigned int)eProfile);
4445             return false;
4446         }
4447 
4448         DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
4449                 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
4450                 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
4451                 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
4452 
4453         if (mb_per_frame >= 3600) {
4454             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4455                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4456 
4457             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4458                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4459         } else {
4460             switch (eLevel) {
4461                 case OMX_VIDEO_MPEG4Level0:
4462                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
4463                     break;
4464                 case OMX_VIDEO_MPEG4Level0b:
4465                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
4466                     break;
4467                 case OMX_VIDEO_MPEG4Level1:
4468                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
4469                     break;
4470                 case OMX_VIDEO_MPEG4Level2:
4471                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
4472                     break;
4473                 case OMX_VIDEO_MPEG4Level3:
4474                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
4475                     break;
4476                 case OMX_VIDEO_MPEG4Level4a:
4477                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
4478                     break;
4479                 case OMX_VIDEO_MPEG4Level5:
4480                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4481                     break;
4482                 default:
4483                     return false;
4484                     // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
4485                     break;
4486             }
4487         }
4488     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4489 
4490         switch (eProfile) {
4491             case OMX_VIDEO_H263ProfileBaseline:
4492                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
4493                 break;
4494             case OMX_VIDEO_H263ProfileH320Coding:
4495                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
4496                 break;
4497             case OMX_VIDEO_H263ProfileBackwardCompatible:
4498                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
4499                 break;
4500             case OMX_VIDEO_H263ProfileISWV2:
4501                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
4502                 break;
4503             case OMX_VIDEO_H263ProfileISWV3:
4504                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
4505                 break;
4506             case OMX_VIDEO_H263ProfileHighCompression:
4507                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
4508                 break;
4509             case OMX_VIDEO_H263ProfileInternet:
4510                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
4511                 break;
4512             case OMX_VIDEO_H263ProfileInterlace:
4513                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
4514                 break;
4515             case OMX_VIDEO_H263ProfileHighLatency:
4516                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
4517                 break;
4518             default:
4519                 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
4520                         requested_profile.profile);
4521                 return false;
4522         }
4523 
4524         //profile level
4525         switch (eLevel) {
4526             case OMX_VIDEO_H263Level10:
4527                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
4528                 break;
4529             case OMX_VIDEO_H263Level20:
4530                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
4531                 break;
4532             case OMX_VIDEO_H263Level30:
4533                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
4534                 break;
4535             case OMX_VIDEO_H263Level40:
4536                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
4537                 break;
4538             case OMX_VIDEO_H263Level45:
4539                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
4540                 break;
4541             case OMX_VIDEO_H263Level50:
4542                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
4543                 break;
4544             case OMX_VIDEO_H263Level60:
4545                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
4546                 break;
4547             case OMX_VIDEO_H263Level70:
4548                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
4549                 break;
4550             default:
4551                 return false;
4552                 break;
4553         }
4554     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4555         if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
4556             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
4557         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
4558                   eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
4559             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
4560         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh ||
4561                   eProfile == OMX_VIDEO_AVCProfileConstrainedHigh) {
4562             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
4563         } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
4564             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
4565         } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
4566             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
4567         } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
4568             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
4569         } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
4570             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
4571         } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
4572             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
4573         } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
4574             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
4575         } else {
4576             DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
4577                     requested_profile.profile);
4578             return false;
4579         }
4580 
4581         //profile level
4582         switch (eLevel) {
4583             case OMX_VIDEO_AVCLevel1:
4584                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
4585                 break;
4586             case OMX_VIDEO_AVCLevel1b:
4587                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
4588                 break;
4589             case OMX_VIDEO_AVCLevel11:
4590                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
4591                 break;
4592             case OMX_VIDEO_AVCLevel12:
4593                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
4594                 break;
4595             case OMX_VIDEO_AVCLevel13:
4596                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
4597                 break;
4598             case OMX_VIDEO_AVCLevel2:
4599                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
4600                 break;
4601             case OMX_VIDEO_AVCLevel21:
4602                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
4603                 break;
4604             case OMX_VIDEO_AVCLevel22:
4605                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
4606                 break;
4607             case OMX_VIDEO_AVCLevel3:
4608                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
4609                 break;
4610             case OMX_VIDEO_AVCLevel31:
4611                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
4612                 break;
4613             case OMX_VIDEO_AVCLevel32:
4614                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
4615                 break;
4616             case OMX_VIDEO_AVCLevel4:
4617                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
4618                 break;
4619             case OMX_VIDEO_AVCLevel41:
4620                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
4621                 break;
4622             case OMX_VIDEO_AVCLevel42:
4623                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
4624                 break;
4625             case OMX_VIDEO_AVCLevel5:
4626                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
4627                 break;
4628             case OMX_VIDEO_AVCLevel51:
4629                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
4630                 break;
4631             case OMX_VIDEO_AVCLevel52:
4632                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4633                 break;
4634             case OMX_VIDEO_AVCLevelMax:
4635                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4636                 break;
4637             default :
4638                 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
4639                         requested_level.level);
4640                 return false;
4641                 break;
4642         }
4643     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4644         if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
4645             DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
4646                         (unsigned int)eProfile);
4647             return false;
4648         }
4649         requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
4650         m_profile_set = true;
4651         switch(eLevel) {
4652             case OMX_VIDEO_VP8Level_Version0:
4653                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
4654                 break;
4655             case OMX_VIDEO_VP8Level_Version1:
4656                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
4657                 break;
4658             default:
4659                 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
4660                             (unsigned int)eLevel);
4661                 return false;
4662                 break;
4663         }
4664     }  else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4665         if (eProfile == OMX_VIDEO_HEVCProfileMain) {
4666             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
4667         } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
4668             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
4669         } else {
4670             DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
4671                     requested_profile.profile);
4672             return false;
4673         }
4674 
4675         //profile level
4676         switch (eLevel) {
4677             case OMX_VIDEO_HEVCMainTierLevel1:
4678                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
4679                 break;
4680             case OMX_VIDEO_HEVCHighTierLevel1:
4681                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
4682                 break;
4683             case OMX_VIDEO_HEVCMainTierLevel2:
4684                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
4685                 break;
4686             case OMX_VIDEO_HEVCHighTierLevel2:
4687                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
4688                 break;
4689             case OMX_VIDEO_HEVCMainTierLevel21:
4690                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
4691                 break;
4692             case OMX_VIDEO_HEVCHighTierLevel21:
4693                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
4694                 break;
4695             case OMX_VIDEO_HEVCMainTierLevel3:
4696                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
4697                 break;
4698             case OMX_VIDEO_HEVCHighTierLevel3:
4699                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
4700                 break;
4701             case OMX_VIDEO_HEVCMainTierLevel31:
4702                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
4703                 break;
4704             case OMX_VIDEO_HEVCHighTierLevel31:
4705                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
4706                 break;
4707             case OMX_VIDEO_HEVCMainTierLevel4:
4708                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
4709                 break;
4710             case OMX_VIDEO_HEVCHighTierLevel4:
4711                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
4712                 break;
4713             case OMX_VIDEO_HEVCMainTierLevel41:
4714                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
4715                 break;
4716             case OMX_VIDEO_HEVCHighTierLevel41:
4717                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
4718                 break;
4719             case OMX_VIDEO_HEVCMainTierLevel5:
4720                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
4721                 break;
4722             case OMX_VIDEO_HEVCHighTierLevel5:
4723                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
4724                 break;
4725             case OMX_VIDEO_HEVCMainTierLevel51:
4726                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
4727                 break;
4728             case OMX_VIDEO_HEVCHighTierLevel51:
4729                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
4730                 break;
4731             case OMX_VIDEO_HEVCMainTierLevel52:
4732                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
4733                 break;
4734             case OMX_VIDEO_HEVCHighTierLevel52:
4735                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
4736                 break;
4737             case OMX_VIDEO_HEVCMainTierLevel6:
4738                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
4739                 break;
4740             case OMX_VIDEO_HEVCHighTierLevel6:
4741                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
4742                 break;
4743             case OMX_VIDEO_HEVCMainTierLevel61:
4744                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
4745                 break;
4746             case OMX_VIDEO_HEVCHighTierLevel61:
4747                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
4748                 break;
4749             default :
4750                 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
4751                         requested_level.level);
4752                 return false;
4753         }
4754     }
4755 
4756     if (!m_profile_set) {
4757         int rc;
4758         struct v4l2_control control;
4759 
4760         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4761             control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
4762         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4763             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
4764         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4765             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
4766         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4767             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
4768         } else {
4769             DEBUG_PRINT_ERROR("Wrong CODEC");
4770             return false;
4771         }
4772 
4773         control.value = requested_profile.profile;
4774 
4775         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4776         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4777 
4778         if (rc) {
4779             DEBUG_PRINT_ERROR("Failed to set control");
4780             return false;
4781         }
4782 
4783         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4784 
4785         codec_profile.profile = control.value;
4786         m_profile_set = true;
4787     }
4788 
4789     if (!m_level_set) {
4790         int rc;
4791         struct v4l2_control control;
4792 
4793         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4794             control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
4795         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4796             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
4797         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4798             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
4799         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4800             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
4801         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4802             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
4803         } else {
4804             DEBUG_PRINT_ERROR("Wrong CODEC");
4805             return false;
4806         }
4807 
4808         control.value = requested_level.level;
4809 
4810         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4811         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4812 
4813         if (rc) {
4814             DEBUG_PRINT_ERROR("Failed to set control");
4815             return false;
4816         }
4817 
4818         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4819 
4820         profile_level.level = control.value;
4821         m_level_set = true;
4822     }
4823 
4824     return true;
4825 }
4826 
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)4827 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
4828 {
4829 
4830     struct venc_voptimingcfg vop_timing_cfg;
4831 
4832     DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
4833             (unsigned int)TimeIncRes);
4834 
4835     vop_timing_cfg.voptime_resolution = TimeIncRes;
4836 
4837     voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
4838     return true;
4839 }
4840 
venc_set_intra_period_config(OMX_U32 nPFrames,OMX_U32 nBFrames)4841 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
4842 #if _ANDROID_
4843     // Android defines nBFrames as number of Bs between I OR P
4844     // Per the spec, nBFrames is number of Bs between I
4845     OMX_U32 nBs = nBFrames * (nPFrames + 1);
4846     DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
4847     nBFrames = nBs;
4848 #endif //_ANDROID_
4849    return venc_set_intra_period(nPFrames, nBFrames);
4850 }
4851 
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)4852 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
4853 {
4854 
4855     DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
4856     int rc;
4857     struct v4l2_control control;
4858     int pframe = 0, bframe = 0;
4859 
4860     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
4861             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
4862             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
4863             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
4864             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4865         nBFrames=0;
4866     }
4867 
4868     if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
4869         DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
4870         return false;
4871     }
4872 
4873     intra_period.num_pframes = nPFrames;
4874     intra_period.num_bframes = nBFrames;
4875 
4876     if (!venc_calibrate_gop() && !is_thulium_v1)
4877     {
4878         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4879         return false;
4880     }
4881 
4882     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4883     control.value = intra_period.num_pframes;
4884     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4885 
4886     if (rc) {
4887         DEBUG_PRINT_ERROR("Failed to set control");
4888         return false;
4889     }
4890 
4891     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4892 
4893     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4894     control.value = intra_period.num_bframes;
4895     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4896     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4897 
4898     if (rc) {
4899         DEBUG_PRINT_ERROR("Failed to set control");
4900         return false;
4901     }
4902 
4903     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
4904 
4905     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
4906         m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4907         control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4908         control.value = 1;
4909 
4910         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4911 
4912         if (rc) {
4913             DEBUG_PRINT_ERROR("Failed to set control");
4914             return false;
4915         }
4916         idrperiod.idrperiod = 1;
4917     }
4918     return true;
4919 }
4920 
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)4921 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
4922 {
4923     int rc = 0;
4924     struct v4l2_control control;
4925     DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
4926             (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
4927 
4928     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
4929         DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
4930         return false;
4931     }
4932 
4933     if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
4934         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4935         return false;
4936     }
4937 
4938     if (!intra_period.num_bframes)
4939         intra_period.num_pframes = nPFrames;
4940     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4941     control.value = nIDRPeriod;
4942 
4943     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4944 
4945     if (rc) {
4946         DEBUG_PRINT_ERROR("Failed to set control");
4947         return false;
4948     }
4949 
4950     idrperiod.idrperiod = nIDRPeriod;
4951     return true;
4952 }
4953 
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)4954 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
4955 {
4956     int rc = 0;
4957     struct v4l2_control control;
4958 
4959     DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
4960 
4961     if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
4962             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
4963 
4964         control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
4965         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4966 
4967         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4968         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4969 
4970         if (rc) {
4971             DEBUG_PRINT_ERROR("Failed to set control");
4972             return false;
4973         }
4974 
4975         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4976         entropy.longentropysel = control.value;
4977 
4978         if (i_cabac_level == 0) {
4979             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
4980         } else if (i_cabac_level == 1) {
4981             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
4982         } else if (i_cabac_level == 2) {
4983             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
4984         }
4985 
4986         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
4987         //control.value = entropy_cfg.cabacmodel;
4988         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4989         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4990 
4991         if (rc) {
4992             DEBUG_PRINT_ERROR("Failed to set control");
4993             return false;
4994         }
4995 
4996         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4997         entropy.cabacmodel=control.value;
4998     } else if (!enable) {
4999         control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
5000         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
5001         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5002         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5003 
5004         if (rc) {
5005             DEBUG_PRINT_ERROR("Failed to set control");
5006             return false;
5007         }
5008 
5009         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5010         entropy.longentropysel=control.value;
5011     } else {
5012         DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
5013         return false;
5014     }
5015 
5016     return true;
5017 }
5018 
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)5019 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
5020 {
5021     int rc;
5022     struct v4l2_control control;
5023     bool status = true;
5024 
5025     if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
5026         control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
5027     } else {
5028         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5029     }
5030 
5031     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5032     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5033     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5034 
5035     if (rc) {
5036         DEBUG_PRINT_ERROR("Failed to set control");
5037         return false;
5038     }
5039 
5040     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5041     multislice.mslice_mode=control.value;
5042 
5043     if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
5044 
5045         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
5046         control.value = nSlicesize;
5047         DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
5048         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5049 
5050         if (rc) {
5051             DEBUG_PRINT_ERROR("Failed to set control");
5052             return false;
5053         }
5054 
5055         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5056         multislice.mslice_size=control.value;
5057 
5058     }
5059 
5060     return status;
5061 }
5062 
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)5063 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
5064 {
5065     bool status = true;
5066     int rc;
5067     struct v4l2_control control_mode,control_mbs;
5068     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
5069 
5070     // There is no disabled mode.  Disabled mode is indicated by a 0 count.
5071     if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
5072         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
5073         return status;
5074     } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
5075             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5076         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
5077         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
5078         control_mbs.value=irMBs;
5079     } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
5080             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5081         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
5082         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5083         control_mbs.value=irMBs;
5084     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
5085             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5086         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
5087     } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
5088             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5089         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
5090         control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5091         control_mbs.value = irMBs;
5092     } else {
5093         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
5094                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
5095         return false;
5096     }
5097 
5098     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
5099     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
5100 
5101     if (rc) {
5102         DEBUG_PRINT_ERROR("Failed to set control");
5103         return false;
5104     }
5105 
5106     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
5107 
5108     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
5109     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
5110 
5111     if (rc) {
5112         DEBUG_PRINT_ERROR("Failed to set control");
5113         return false;
5114     }
5115 
5116     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
5117 
5118     intra_refresh.irmode = control_mode.value;
5119     intra_refresh.mbcount = control_mbs.value;
5120 
5121     return status;
5122 }
5123 
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)5124 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
5125 {
5126     bool status = true;
5127     struct venc_headerextension hec_cfg;
5128     struct venc_multiclicecfg multislice_cfg;
5129     int rc;
5130     OMX_U32 resynchMarkerSpacingBytes = 0;
5131     struct v4l2_control control;
5132 
5133     memset(&control, 0, sizeof(control));
5134 
5135     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5136         if (error_resilience->bEnableHEC) {
5137             hec_cfg.header_extension = 1;
5138         } else {
5139             hec_cfg.header_extension = 0;
5140         }
5141 
5142         hec.header_extension = error_resilience->bEnableHEC;
5143     }
5144 
5145     if (error_resilience->bEnableRVLC) {
5146         DEBUG_PRINT_ERROR("RVLC is not Supported");
5147         return false;
5148     }
5149 
5150     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5151             (error_resilience->bEnableDataPartitioning)) {
5152         DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
5153         return false;
5154     }
5155 
5156     if (error_resilience->nResynchMarkerSpacing) {
5157         resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
5158         resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
5159     }
5160     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5161             (error_resilience->nResynchMarkerSpacing)) {
5162         multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
5163         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5164         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5165         control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
5166     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
5167             error_resilience->bEnableDataPartitioning) {
5168         multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
5169         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5170         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5171         control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
5172     } else {
5173         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
5174         multislice_cfg.mslice_size = 0;
5175         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5176         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5177     }
5178 
5179     DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
5180             multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
5181     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5182     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5183 
5184     if (rc) {
5185        DEBUG_PRINT_ERROR("Failed to set Slice mode control");
5186         return false;
5187     }
5188 
5189     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5190     multislice.mslice_mode=control.value;
5191 
5192     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
5193     control.value = resynchMarkerSpacingBytes;
5194     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5195 
5196     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5197 
5198     if (rc) {
5199        DEBUG_PRINT_ERROR("Failed to set MAX MB control");
5200         return false;
5201     }
5202 
5203     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5204     multislice.mslice_mode = multislice_cfg.mslice_mode;
5205     multislice.mslice_size = multislice_cfg.mslice_size;
5206     return status;
5207 }
5208 
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)5209 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
5210 {
5211     int rc;
5212     struct v4l2_control control;
5213     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
5214 
5215     if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
5216         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
5217     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
5218         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
5219     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
5220         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
5221     }
5222 
5223     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5224     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5225 
5226     if (rc) {
5227         return false;
5228     }
5229 
5230     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5231 
5232     dbkfilter.db_mode=control.value;
5233 
5234     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
5235     control.value=0;
5236 
5237     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5238     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5239 
5240     if (rc) {
5241         return false;
5242     }
5243 
5244     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5245     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
5246     control.value=0;
5247     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5248     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5249 
5250     if (rc) {
5251         return false;
5252     }
5253 
5254     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5255 
5256 
5257     dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
5258     return true;
5259 }
5260 
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)5261 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
5262 {
5263     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
5264             (unsigned int)nTargetBitrate);
5265     struct v4l2_control control;
5266     int rc = 0;
5267     control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
5268     control.value = nTargetBitrate;
5269 
5270     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5271     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5272 
5273     if (rc) {
5274         DEBUG_PRINT_ERROR("Failed to set control");
5275         return false;
5276     }
5277 
5278     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5279 
5280 
5281     m_sVenc_cfg.targetbitrate = control.value;
5282     bitrate.target_bitrate = control.value;
5283 
5284     if (!config) {
5285         m_level_set = false;
5286 
5287         if (venc_set_profile_level(0, 0)) {
5288             DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
5289         }
5290     }
5291 
5292     // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
5293     //  has been specified
5294     if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
5295         OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
5296                 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5297 
5298         DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
5299         for (OMX_U32 i = 0; i < numLayers; ++i) {
5300             layerBitrates[i] =
5301                     (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
5302             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
5303                     i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
5304                     layerBitrates[i], bitrate.target_bitrate);
5305         }
5306         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
5307             return false;
5308         }
5309     }
5310 
5311     return true;
5312 }
5313 
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)5314 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
5315 {
5316     struct v4l2_streamparm parm;
5317     int rc = 0;
5318     struct venc_framerate frame_rate_cfg;
5319     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
5320     parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5321     parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
5322     parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
5323 
5324     if (frame_rate_cfg.fps_numerator > 0)
5325         rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
5326 
5327     if (rc) {
5328         DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
5329         return false;
5330     }
5331 
5332     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
5333     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
5334 
5335     if (!config) {
5336         m_level_set = false;
5337 
5338         if (venc_set_profile_level(0, 0)) {
5339             DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
5340         }
5341     }
5342 
5343     return true;
5344 }
5345 
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)5346 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
5347 {
5348     struct v4l2_format fmt;
5349     int color_space = 0;
5350     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
5351 
5352     switch ((int)color_format) {
5353         case OMX_COLOR_FormatYUV420SemiPlanar:
5354         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
5355             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
5356             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5357             break;
5358         case QOMX_COLOR_FormatYVU420SemiPlanar:
5359             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
5360             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5361             break;
5362         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
5363             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
5364             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5365             break;
5366         case QOMX_COLOR_Format32bitRGBA8888:
5367             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
5368             break;
5369         case QOMX_COLOR_Format32bitRGBA8888Compressed:
5370             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
5371             break;
5372         default:
5373             DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
5374             m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
5375             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5376             DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
5377             break;
5378     }
5379 
5380     memset(&fmt, 0, sizeof(fmt));
5381     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5382     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
5383     fmt.fmt.pix_mp.colorspace = color_space;
5384     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
5385     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
5386 
5387     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5388         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
5389         return false;
5390     }
5391 
5392     return true;
5393 }
5394 
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)5395 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
5396 {
5397     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
5398 
5399     if (intra_vop_refresh == OMX_TRUE) {
5400         struct v4l2_control control;
5401         int rc;
5402         control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
5403         control.value = 1;
5404        DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5405         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5406 
5407         if (rc) {
5408            DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
5409             return false;
5410         }
5411 
5412        DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5413     } else {
5414         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
5415     }
5416 
5417     return true;
5418 }
5419 
venc_set_deinterlace(OMX_U32 enable)5420 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
5421 {
5422     DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
5423     struct v4l2_control control;
5424     int rc;
5425     control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
5426     if (enable)
5427         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5428     else
5429         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5430 
5431     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5432     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5433     if (rc) {
5434         DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
5435         return false;
5436     }
5437     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5438     deinterlace_enabled = true;
5439     return true;
5440 }
5441 
venc_calibrate_gop()5442 bool venc_dev::venc_calibrate_gop()
5443 {
5444     int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
5445     int num_sub_gops_in_a_gop;
5446     nPframes = intra_period.num_pframes;
5447     nBframes = intra_period.num_bframes;
5448     nLayers = hier_layers.numlayers;
5449     if (temporal_layers_config.nPLayers) {
5450         nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5451     }
5452 
5453     if (!nPframes && nLayers) {
5454         DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
5455         return false;
5456     }
5457 
5458     if (nLayers > 1) { /*Multi-layer encoding*/
5459         sub_gop_size = 1 << (nLayers - 1);
5460         /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
5461          * below calculations we are ignoring +1 . Ignoring +1 in below
5462          * calculations is not a mistake but intentional.
5463          */
5464         gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
5465         num_sub_gops_in_a_gop = gop_size/sub_gop_size;
5466         if (nBframes) { /*Hier-B case*/
5467         /*
5468             * Frame Type--> I  B  B  B  P  B  B  B  P  I  B  B  P ...
5469             * Layer -->     0  2  1  2  0  2  1  2  0  0  2  1  2 ...
5470             * nPframes = 2, nBframes = 6, nLayers = 3
5471             *
5472             * Intention is to keep the intraperiod as close as possible to what is desired
5473             * by the client while adjusting nPframes and nBframes to meet other constraints.
5474             * eg1: Input by client: nPframes =  9, nBframes = 14, nLayers = 2
5475             *    Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
5476             *
5477             * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
5478             *    Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
5479             */
5480             nPframes = num_sub_gops_in_a_gop;
5481             nBframes = gop_size - nPframes;
5482         } else { /*Hier-P case*/
5483             /*
5484             * Frame Type--> I  P  P  P  P  P  P  P  I  P  P  P  P ...
5485             * Layer-->      0  2  1  2  0  2  1  2  0  2  1  2  0 ...
5486             * nPframes =  7, nBframes = 0, nLayers = 3
5487             *
5488             * Intention is to keep the intraperiod as close as possible to what is desired
5489             * by the client while adjusting nPframes and nBframes to meet other constraints.
5490             * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
5491             *    Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
5492             *
5493             * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
5494             *     Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
5495             */
5496             nPframes = gop_size - 1;
5497         }
5498     } else { /*Single-layer encoding*/
5499         if (nBframes) {
5500             /* I  P  B  B  B  P  B  B  B   P   B   B   B   I   P   B   B...
5501             *  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17...
5502             * nPframes = 3, nBframes = 9, nLayers = 0
5503             *
5504             * ratio is rounded,
5505             * eg1: nPframes = 9, nBframes = 11 => ratio = 1
5506             * eg2: nPframes = 9, nBframes = 16 => ratio = 2
5507             */
5508             ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
5509             nBframes = ratio * nPframes;
5510         }
5511     }
5512     DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
5513         intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
5514     intra_period.num_pframes = nPframes;
5515     intra_period.num_bframes = nBframes;
5516     hier_layers.numlayers = nLayers;
5517     return true;
5518 }
5519 
venc_set_bitrate_type(OMX_U32 type)5520 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
5521 {
5522     struct v4l2_control control;
5523     int rc = 0;
5524     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
5525     control.value = type;
5526     DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
5527     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5528     if (rc) {
5529         DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
5530             bitrate_type_string(type));
5531         return false;
5532     }
5533     return true;
5534 }
5535 
venc_set_layer_bitrates(OMX_U32 * layerBitrate,OMX_U32 numLayers)5536 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
5537 {
5538     DEBUG_PRINT_LOW("venc_set_layer_bitrates");
5539     struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
5540     struct v4l2_ext_controls controls;
5541     int rc = 0;
5542     OMX_U32 i;
5543 
5544     if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
5545         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
5546         return false;
5547     }
5548 
5549     for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
5550         if (!layerBitrate[i]) {
5551             DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
5552             return false;
5553         } else {
5554             ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
5555             ctrl[i].value = layerBitrate[i];
5556         }
5557     }
5558     controls.count = numLayers;
5559     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5560     controls.controls = ctrl;
5561 
5562     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5563     if (rc) {
5564         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
5565         return false;
5566     }
5567 
5568     DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
5569     return true;
5570 }
5571 
venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE * hhp)5572 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
5573 {
5574     DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
5575     struct v4l2_control control;
5576     int rc;
5577 
5578     if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
5579         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5580         return false;
5581     }
5582 
5583     if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
5584         DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
5585         return false;
5586     }
5587     if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
5588        DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
5589        return false;
5590     }
5591 
5592     hier_layers.numlayers = hhp->nHpLayers;
5593     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5594         hier_layers.hier_mode = HIER_P_HYBRID;
5595     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5596         hier_layers.hier_mode = HIER_P;
5597     }
5598     if (venc_calibrate_gop()) {
5599      // Update the driver with the new nPframes and nBframes
5600         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
5601         control.value = intra_period.num_pframes;
5602         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5603         if (rc) {
5604             DEBUG_PRINT_ERROR("Failed to set control");
5605             return false;
5606         }
5607 
5608         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
5609         control.value = intra_period.num_bframes;
5610         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5611         if (rc) {
5612             DEBUG_PRINT_ERROR("Failed to set control");
5613             return false;
5614         }
5615         DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
5616                          intra_period.num_pframes, intra_period.num_bframes);
5617     } else {
5618         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5619         return false;
5620     }
5621     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5622         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
5623     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5624         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
5625     }
5626     control.value = hhp->nHpLayers - 1;
5627 
5628     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
5629                     control.id, control.value);
5630 
5631     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5632     if (rc) {
5633         DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
5634         return false;
5635     }
5636 
5637     DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
5638                     control.id, control.value);
5639     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5640         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
5641         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
5642         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5643             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5644             return false;
5645         }
5646     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5647         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
5648         control.value = hhp->nHpLayers - 1;
5649         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5650             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5651             return false;
5652         }
5653     } else {
5654         DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
5655         return false;
5656     }
5657 
5658     if(venc_set_session_qp_range (hhp->nMinQuantizer,
5659                 hhp->nMaxQuantizer) == false) {
5660         DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
5661             (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
5662         return false;
5663     } else {
5664         session_qp_values.minqp = hhp->nMinQuantizer;
5665         session_qp_values.maxqp = hhp->nMaxQuantizer;
5666     }
5667 
5668     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
5669     for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
5670         layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
5671         hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
5672         DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
5673     }
5674     if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
5675        DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
5676             hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
5677             hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
5678             hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
5679        return false;
5680     }
5681     hybrid_hp.nHpLayers = hhp->nHpLayers;
5682 
5683     // Set this or else the layer0 bitrate will be overwritten by
5684     // default value in component
5685     m_sVenc_cfg.targetbitrate  = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
5686     hybrid_hp.nHpLayers = hhp->nHpLayers;
5687     hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
5688     hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
5689     hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
5690     return true;
5691 }
5692 
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)5693 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
5694 {
5695     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
5696     struct v4l2_ext_control ctrl[2];
5697     struct v4l2_ext_controls controls;
5698     int rc;
5699 
5700     if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
5701         DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
5702         return false;
5703     }
5704 
5705     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
5706     if (enable)
5707         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
5708     else
5709         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
5710 
5711     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
5712     if (enable && count > 0)
5713         ctrl[1].value = count;
5714     else if (enable)
5715         ctrl[1].value = 1;
5716     else
5717         ctrl[1].value = 0;
5718 
5719     controls.count = 2;
5720     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5721     controls.controls = ctrl;
5722 
5723     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
5724                     controls.controls[0].id, controls.controls[0].value,
5725                     controls.controls[1].id, controls.controls[1].value);
5726 
5727     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5728     if (rc) {
5729         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5730         return false;
5731     }
5732     ltrinfo.enabled = enable;
5733     ltrinfo.count = count;
5734 
5735     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
5736                     controls.controls[0].id, controls.controls[0].value,
5737                     controls.controls[1].id, controls.controls[1].value);
5738 
5739     if (!venc_set_profile_level(0, 0)) {
5740         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
5741                 __func__);
5742     } else {
5743         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
5744                 __func__, codec_profile.profile, profile_level.level);
5745     }
5746 
5747     return true;
5748 }
5749 
venc_set_useltr(OMX_U32 frameIdx)5750 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
5751 {
5752     DEBUG_PRINT_LOW("venc_use_goldenframe");
5753     int rc = true;
5754     struct v4l2_control control;
5755 
5756     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
5757     control.value = frameIdx;
5758 
5759     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5760     if (rc) {
5761         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
5762         return false;
5763     }
5764 
5765     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5766                     control.id, control.value);
5767     return true;
5768 }
5769 
venc_set_markltr(OMX_U32 frameIdx)5770 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
5771 {
5772     DEBUG_PRINT_LOW("venc_set_goldenframe");
5773     int rc = true;
5774     struct v4l2_control control;
5775 
5776     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
5777     control.value = frameIdx;
5778 
5779     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5780     if (rc) {
5781         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5782         return false;
5783     }
5784 
5785     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5786                     control.id, control.value);
5787     return true;
5788 }
5789 
venc_set_vpe_rotation(OMX_S32 rotation_angle)5790 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
5791 {
5792     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
5793     struct v4l2_control control;
5794     int rc;
5795     struct v4l2_format fmt;
5796     struct v4l2_requestbuffers bufreq;
5797 
5798     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
5799     if (rotation_angle == 0)
5800         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
5801     else if (rotation_angle == 90)
5802         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
5803     else if (rotation_angle == 180)
5804         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
5805     else if (rotation_angle == 270)
5806         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
5807     else {
5808         DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
5809         return false;
5810     }
5811 
5812     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5813     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5814     if (rc) {
5815         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
5816         return false;
5817     }
5818     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5819 
5820     memset(&fmt, 0, sizeof(fmt));
5821     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5822     if (rotation_angle == 90 || rotation_angle == 270) {
5823         OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
5824         OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
5825         m_sVenc_cfg.dvs_height = nHeight;
5826         m_sVenc_cfg.dvs_width = nWidth;
5827         DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
5828                 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
5829     }
5830 
5831     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
5832     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
5833     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
5834     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5835         DEBUG_PRINT_ERROR("Failed to set format on capture port");
5836         return false;
5837     }
5838 
5839     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
5840     bufreq.memory = V4L2_MEMORY_USERPTR;
5841     bufreq.count = m_sOutput_buff_property.actualcount;
5842     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5843     if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
5844         DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
5845             return false;
5846     }
5847     if (bufreq.count >= m_sOutput_buff_property.mincount)
5848         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
5849 
5850     return true;
5851 }
5852 
venc_set_searchrange()5853 bool venc_dev::venc_set_searchrange()
5854 {
5855     DEBUG_PRINT_LOW("venc_set_searchrange");
5856     struct v4l2_control control;
5857     struct v4l2_ext_control ctrl[6];
5858     struct v4l2_ext_controls controls;
5859     int rc;
5860 
5861     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5862         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5863         ctrl[0].value = 16;
5864         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5865         ctrl[1].value = 4;
5866         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5867         ctrl[2].value = 16;
5868         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5869         ctrl[3].value = 4;
5870         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5871         ctrl[4].value = 12;
5872         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5873         ctrl[5].value = 4;
5874     } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
5875                (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
5876         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5877         ctrl[0].value = 16;
5878         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5879         ctrl[1].value = 4;
5880         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5881         ctrl[2].value = 16;
5882         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5883         ctrl[3].value = 4;
5884         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5885         ctrl[4].value = 12;
5886         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5887         ctrl[5].value = 4;
5888     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5889         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5890         ctrl[0].value = 4;
5891         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5892         ctrl[1].value = 4;
5893         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5894         ctrl[2].value = 4;
5895         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5896         ctrl[3].value = 4;
5897         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5898         ctrl[4].value = 4;
5899         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5900         ctrl[5].value = 4;
5901     } else {
5902         DEBUG_PRINT_ERROR("Invalid codec type");
5903         return false;
5904     }
5905     controls.count = 6;
5906     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5907     controls.controls = ctrl;
5908 
5909     DEBUG_PRINT_LOW(" Calling IOCTL set control for"
5910         "id=%x, val=%d id=%x, val=%d"
5911         "id=%x, val=%d id=%x, val=%d"
5912         "id=%x, val=%d id=%x, val=%d",
5913         controls.controls[0].id, controls.controls[0].value,
5914         controls.controls[1].id, controls.controls[1].value,
5915         controls.controls[2].id, controls.controls[2].value,
5916         controls.controls[3].id, controls.controls[3].value,
5917         controls.controls[4].id, controls.controls[4].value,
5918         controls.controls[5].id, controls.controls[5].value);
5919 
5920     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5921     if (rc) {
5922         DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
5923         return false;
5924     }
5925     return true;
5926 }
5927 
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)5928 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
5929 {
5930     bool status = true;
5931     struct v4l2_control control;
5932     int rc = 0;
5933     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
5934 
5935     switch (eControlRate) {
5936         case OMX_Video_ControlRateDisable:
5937             control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
5938             break;
5939         case OMX_Video_ControlRateVariableSkipFrames:
5940             (supported_rc_modes & RC_VBR_VFR) ?
5941                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
5942                 status = false;
5943             break;
5944         case OMX_Video_ControlRateVariable:
5945             (supported_rc_modes & RC_VBR_CFR) ?
5946                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
5947                 status = false;
5948             break;
5949         case OMX_Video_ControlRateConstantSkipFrames:
5950             (supported_rc_modes & RC_CBR_VFR) ?
5951                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
5952                 status = false;
5953             break;
5954         case OMX_Video_ControlRateConstant:
5955             (supported_rc_modes & RC_CBR_CFR) ?
5956                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
5957                 status = false;
5958             break;
5959         default:
5960             status = false;
5961             break;
5962     }
5963 
5964     if (status) {
5965 
5966         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5967         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5968 
5969         if (rc) {
5970             DEBUG_PRINT_ERROR("Failed to set control");
5971             return false;
5972         }
5973 
5974         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5975 
5976         rate_ctrl.rcmode = control.value;
5977     }
5978 
5979 #ifdef _VQZIP_
5980     if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
5981         && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5982         /* Enable VQZIP SEI by default for camcorder RC modes */
5983 
5984         control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
5985         control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
5986         DEBUG_PRINT_HIGH("Set VQZIP SEI:");
5987         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
5988             DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
5989         }
5990     }
5991 #endif //_VQZIP_
5992 
5993     return status;
5994 }
5995 
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)5996 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
5997 {
5998     bool status = true;
5999     struct v4l2_control control;
6000     int rc = 0;
6001     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
6002 
6003     switch (ePerfLevel) {
6004     case OMX_QCOM_PerfLevelNominal:
6005         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
6006         break;
6007     case OMX_QCOM_PerfLevelTurbo:
6008         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
6009         break;
6010     default:
6011         status = false;
6012         break;
6013     }
6014 
6015     if (status) {
6016         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6017         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6018 
6019         if (rc) {
6020             DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
6021             return false;
6022         }
6023 
6024         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6025     }
6026     return status;
6027 }
6028 
venc_set_perf_mode(OMX_U32 mode)6029 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
6030 {
6031     struct v4l2_control control;
6032     if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
6033         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
6034         control.value = mode;
6035         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6036         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6037             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6038             return false;
6039         }
6040         return true;
6041     } else {
6042         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
6043         return false;
6044     }
6045 }
6046 
venc_set_qp(OMX_U32 nQp)6047 bool venc_dev::venc_set_qp(OMX_U32 nQp)
6048 {
6049     struct v4l2_control control;
6050     if (nQp) {
6051         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
6052         control.value = nQp;
6053         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6054         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6055             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6056             return false;
6057         }
6058     } else {
6059         DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
6060         return false;
6061     }
6062     return true;
6063 }
6064 
venc_set_aspectratio(void * nSar)6065 bool venc_dev::venc_set_aspectratio(void *nSar)
6066 {
6067     int rc;
6068     struct v4l2_control control;
6069     struct v4l2_ext_control ctrl[2];
6070     struct v4l2_ext_controls controls;
6071     QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
6072 
6073     sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
6074 
6075     ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
6076     ctrl[0].value = sar->nSARWidth;
6077     ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
6078     ctrl[1].value = sar->nSARHeight;
6079 
6080     controls.count = 2;
6081     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
6082     controls.controls = ctrl;
6083 
6084     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
6085                     controls.controls[0].id, controls.controls[0].value,
6086                     controls.controls[1].id, controls.controls[1].value);
6087 
6088     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
6089     if (rc) {
6090         DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
6091         return false;
6092     }
6093 
6094     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
6095                     controls.controls[0].id, controls.controls[0].value,
6096                     controls.controls[1].id, controls.controls[1].value);
6097     return true;
6098 }
6099 
venc_set_hierp_layers(OMX_U32 hierp_layers)6100 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
6101 {
6102     struct v4l2_control control;
6103     if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
6104             (hierp_layers <= hier_layers.numlayers)) {
6105         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6106         control.value = hierp_layers - 1;
6107         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
6108         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6109             DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
6110             return false;
6111         }
6112         return true;
6113     } else {
6114         DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
6115                 hierp_layers);
6116         return false;
6117     }
6118 }
6119 
venc_set_baselayerid(OMX_U32 baseid)6120 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
6121 {
6122     struct v4l2_control control;
6123     if (hier_layers.hier_mode == HIER_P) {
6124         control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
6125         control.value = baseid;
6126         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6127         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6128             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6129             return false;
6130         }
6131         return true;
6132     } else {
6133         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
6134                 hier_layers.hier_mode);
6135         return false;
6136     }
6137 }
6138 
venc_set_vui_timing_info(OMX_BOOL enable)6139 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
6140 {
6141     struct v4l2_control control;
6142     int rc = 0;
6143     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
6144 
6145     if (enable)
6146         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
6147     else
6148         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
6149 
6150     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
6151     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6152     if (rc) {
6153         DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
6154         return false;
6155     }
6156     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
6157     return true;
6158 }
6159 
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)6160 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
6161 {
6162     struct v4l2_control control;
6163     int rc = 0;
6164     control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
6165     control.value = nPeakBitrate;
6166 
6167     DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
6168 
6169     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6170     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6171 
6172     if (rc) {
6173         DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
6174         return false;
6175     }
6176 
6177     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6178 
6179     return true;
6180 }
6181 
venc_set_vpx_error_resilience(OMX_BOOL enable)6182 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
6183 {
6184     struct v4l2_control control;
6185     int rc = 0;
6186     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
6187 
6188     if (enable)
6189         control.value = 1;
6190     else
6191         control.value = 0;
6192 
6193     DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
6194 
6195     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6196 
6197     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6198     if (rc) {
6199         DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
6200         return false;
6201     }
6202     vpx_err_resilience.enable = 1;
6203     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6204     return true;
6205 }
6206 
venc_set_priority(OMX_U32 priority)6207 bool venc_dev::venc_set_priority(OMX_U32 priority) {
6208     struct v4l2_control control;
6209 
6210     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
6211     if (priority == 0)
6212         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
6213     else
6214         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
6215 
6216     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6217         DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
6218                 priority == 0 ? "ENABLE" : "DISABLE");
6219         return false;
6220     }
6221     return true;
6222 }
6223 
venc_set_operatingrate(OMX_U32 rate)6224 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
6225     struct v4l2_control control;
6226 
6227     control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
6228     control.value = rate;
6229 
6230     DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
6231     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6232 
6233     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6234         hw_overload = errno == EBUSY;
6235         DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
6236                 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
6237         return false;
6238     }
6239     operating_rate = rate;
6240     DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  rate >> 16);
6241     return true;
6242 }
6243 
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)6244 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
6245     char *userptr;
6246     int fd;
6247     unsigned offset;
6248     ssize_t size;
6249     struct msm_vidc_roi_qp_payload *roiData;
6250     if (!roiInfo) {
6251         DEBUG_PRINT_ERROR("No ROI info present");
6252         return false;
6253     }
6254     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
6255         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
6256         DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
6257         return false;
6258     }
6259 
6260     venc_roiqp_log_buffers(roiInfo);
6261     mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
6262     if (!userptr || size < roiInfo->nRoiMBInfoSize) {
6263         DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
6264         return false;
6265     }
6266 
6267     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
6268     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
6269     data->nVersion.nVersion = OMX_SPEC_VERSION;
6270     data->nPortIndex = 0;
6271     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
6272     data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
6273 
6274     roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
6275     roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
6276     roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
6277     roiData->b_roi_info = roiInfo->bUseRoiInfo;
6278     roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
6279     memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
6280 
6281     data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
6282     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
6283     data->nVersion.nVersion = OMX_SPEC_VERSION;
6284     data->nPortIndex = 0;
6285     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
6286     data->nDataSize = 0;
6287     return true;
6288 }
6289 
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)6290 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
6291         OMX_U32 *nMaxBLayers) {
6292 
6293     // no B-layers for all cases
6294     temporal_layers_config.nMaxBLayers = 0;
6295     temporal_layers_config.nMaxLayers = 1;
6296 
6297     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6298             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6299         temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
6300     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6301         temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
6302     }
6303 
6304     *nMaxLayers = temporal_layers_config.nMaxLayers;
6305     *nMaxBLayers = temporal_layers_config.nMaxBLayers;
6306     return true;
6307 }
6308 
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)6309 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
6310         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
6311 
6312     if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6313             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
6314             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
6315         DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
6316         return OMX_ErrorUnsupportedSetting;
6317     }
6318 
6319     if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
6320             (pTemporalParams->nBLayerCountActual != 0 ||
6321              pTemporalParams->nPLayerCountActual != 1)) {
6322         return OMX_ErrorBadParameter;
6323     } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
6324             pTemporalParams->nPLayerCountActual < 1) {
6325         return OMX_ErrorBadParameter;
6326     }
6327 
6328     if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
6329         DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
6330                 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
6331         return OMX_ErrorBadParameter;
6332     } else if (pTemporalParams->nPLayerCountActual >
6333              temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
6334         DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
6335                 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
6336                 temporal_layers_config.nMaxLayers);
6337         return OMX_ErrorBadParameter;
6338     }
6339 
6340     // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
6341     // use hybrid-HP for best results
6342     bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
6343     bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
6344     bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
6345 
6346     // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
6347     bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
6348 
6349     DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
6350             rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
6351 
6352     if (bUseHybridMode &&
6353             !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
6354                 pTemporalParams->nBLayerCountActual,
6355                 0 /* LTR count */, (int) HIER_P_HYBRID)) {
6356         bUseHybridMode = false;
6357         DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
6358     }
6359 
6360     if (intra_period.num_bframes) {
6361         DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
6362         return OMX_ErrorUnsupportedSetting;
6363     }
6364 
6365     if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
6366         DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
6367                 intra_period.num_pframes, intra_period.num_bframes);
6368         return OMX_ErrorUnsupportedSetting;
6369     }
6370 
6371     struct v4l2_control control;
6372     // Num enhancements layers does not include the base-layer
6373     control.value = pTemporalParams->nPLayerCountActual - 1;
6374 
6375     if (bUseHybridMode) {
6376         DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
6377         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6378         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6379             bUseHybridMode = false;
6380             DEBUG_PRINT_ERROR("Failed to set hybrid HP");
6381         } else {
6382             // Disable normal HP if Hybrid mode is being enabled
6383             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6384             control.value = 0;
6385             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6386                 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6387                 return OMX_ErrorUnsupportedSetting;
6388             }
6389             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6390             control.value = 0;
6391             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6392                 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
6393                 return OMX_ErrorUnsupportedSetting;
6394             }
6395         }
6396     }
6397 
6398     if (!bUseHybridMode) {
6399 
6400         // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
6401         if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
6402             DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
6403             return OMX_ErrorUnsupportedSetting;
6404         }
6405 
6406         DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
6407         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6408         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6409             DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
6410             return OMX_ErrorUnsupportedSetting;
6411         }
6412 
6413         // configure max layers for a session.. Okay to use current num-layers as max
6414         //  since we do not plan to support dynamic changes to number of layers
6415         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6416         control.value = pTemporalParams->nPLayerCountActual - 1;
6417         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6418             DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6419             return OMX_ErrorUnsupportedSetting;
6420 
6421         } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
6422             // Disable hybrid mode if it was enabled already
6423             DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
6424             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6425             control.value = 0;
6426             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6427                 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
6428                 return OMX_ErrorUnsupportedSetting;
6429             }
6430         }
6431     }
6432 
6433     // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
6434     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6435         DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
6436         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
6437         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
6438         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6439             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
6440             return OMX_ErrorUnsupportedSetting;
6441         }
6442     }
6443 
6444     temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
6445     temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
6446     temporal_layers_config.nBLayers = 0;
6447 
6448     temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
6449     if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
6450         DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
6451         return OMX_ErrorNone;
6452     }
6453     DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
6454 
6455     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
6456             numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
6457 
6458     OMX_U32 i = 0;
6459     for (; i < numLayers; ++i) {
6460         OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
6461         OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
6462         if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
6463             DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
6464             return OMX_ErrorBadParameter;
6465         } else {
6466             layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
6467             temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
6468             temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
6469             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
6470                     i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
6471         }
6472     }
6473 
6474     temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
6475 
6476     // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
6477     if (bitrate.target_bitrate > 0) {
6478         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
6479             return OMX_ErrorUnsupportedSetting;
6480         }
6481     } else {
6482         DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
6483     }
6484 
6485     return OMX_ErrorNone;
6486 }
6487 
venc_set_temporal_layers_internal()6488 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
6489     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
6490     memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
6491 
6492     if (!temporal_layers_config.nPLayers) {
6493         return OMX_ErrorNone;
6494     }
6495     pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6496     pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
6497     pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
6498     pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6499     pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
6500     pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
6501     pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
6502     if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
6503         for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
6504             pTemporalParams.nBitrateRatios[i] =
6505                     temporal_layers_config.nTemporalLayerBitrateRatio[i];
6506         }
6507     }
6508     return venc_set_temporal_layers(&pTemporalParams);
6509 }
6510 
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6511 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
6512 {
6513     bool status = true;
6514 
6515     if (eProfile == NULL || eLevel == NULL) {
6516         return false;
6517     }
6518 
6519     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6520         switch (codec_profile.profile) {
6521             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6522                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6523                 break;
6524             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6525                 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6526                 break;
6527             default:
6528                 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
6529                 status = false;
6530                 break;
6531         }
6532 
6533         if (!status) {
6534             return status;
6535         }
6536 
6537         //profile level
6538         switch (profile_level.level) {
6539             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
6540                 *eLevel = OMX_VIDEO_MPEG4Level0;
6541                 break;
6542             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
6543                 *eLevel = OMX_VIDEO_MPEG4Level0b;
6544                 break;
6545             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
6546                 *eLevel = OMX_VIDEO_MPEG4Level1;
6547                 break;
6548             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
6549                 *eLevel = OMX_VIDEO_MPEG4Level2;
6550                 break;
6551             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
6552                 *eLevel = OMX_VIDEO_MPEG4Level3;
6553                 break;
6554             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
6555                 *eLevel = OMX_VIDEO_MPEG4Level4;
6556                 break;
6557             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
6558                 *eLevel = OMX_VIDEO_MPEG4Level5;
6559                 break;
6560             default:
6561                 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6562                 status =  false;
6563                 break;
6564         }
6565     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6566         if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
6567             *eProfile = OMX_VIDEO_H263ProfileBaseline;
6568         } else {
6569             *eProfile = OMX_VIDEO_H263ProfileMax;
6570             return false;
6571         }
6572 
6573         switch (profile_level.level) {
6574             case VEN_LEVEL_H263_10:
6575                 *eLevel = OMX_VIDEO_H263Level10;
6576                 break;
6577             case VEN_LEVEL_H263_20:
6578                 *eLevel = OMX_VIDEO_H263Level20;
6579                 break;
6580             case VEN_LEVEL_H263_30:
6581                 *eLevel = OMX_VIDEO_H263Level30;
6582                 break;
6583             case VEN_LEVEL_H263_40:
6584                 *eLevel = OMX_VIDEO_H263Level40;
6585                 break;
6586             case VEN_LEVEL_H263_45:
6587                 *eLevel = OMX_VIDEO_H263Level45;
6588                 break;
6589             case VEN_LEVEL_H263_50:
6590                 *eLevel = OMX_VIDEO_H263Level50;
6591                 break;
6592             case VEN_LEVEL_H263_60:
6593                 *eLevel = OMX_VIDEO_H263Level60;
6594                 break;
6595             case VEN_LEVEL_H263_70:
6596                 *eLevel = OMX_VIDEO_H263Level70;
6597                 break;
6598             default:
6599                 *eLevel = OMX_VIDEO_H263LevelMax;
6600                 status = false;
6601                 break;
6602         }
6603     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6604         switch (codec_profile.profile) {
6605             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6606                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6607                 break;
6608             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6609                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6610                 break;
6611             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6612                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6613                 break;
6614             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6615                 *eProfile = OMX_VIDEO_AVCProfileMain;
6616                 break;
6617             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6618                 *eProfile = OMX_VIDEO_AVCProfileHigh;
6619                 break;
6620             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6621                 *eProfile = OMX_VIDEO_AVCProfileExtended;
6622                 break;
6623             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6624                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6625                 break;
6626             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6627                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6628                 break;
6629             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6630                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6631                 break;
6632             default:
6633                 *eProfile = OMX_VIDEO_AVCProfileMax;
6634                 status = false;
6635                 break;
6636         }
6637 
6638         if (!status) {
6639             return status;
6640         }
6641 
6642         switch (profile_level.level) {
6643             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
6644                 *eLevel = OMX_VIDEO_AVCLevel1;
6645                 break;
6646             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
6647                 *eLevel = OMX_VIDEO_AVCLevel1b;
6648                 break;
6649             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
6650                 *eLevel = OMX_VIDEO_AVCLevel11;
6651                 break;
6652             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
6653                 *eLevel = OMX_VIDEO_AVCLevel12;
6654                 break;
6655             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
6656                 *eLevel = OMX_VIDEO_AVCLevel13;
6657                 break;
6658             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
6659                 *eLevel = OMX_VIDEO_AVCLevel2;
6660                 break;
6661             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
6662                 *eLevel = OMX_VIDEO_AVCLevel21;
6663                 break;
6664             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
6665                 *eLevel = OMX_VIDEO_AVCLevel22;
6666                 break;
6667             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
6668                 *eLevel = OMX_VIDEO_AVCLevel3;
6669                 break;
6670             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
6671                 *eLevel = OMX_VIDEO_AVCLevel31;
6672                 break;
6673             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
6674                 *eLevel = OMX_VIDEO_AVCLevel32;
6675                 break;
6676             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
6677                 *eLevel = OMX_VIDEO_AVCLevel4;
6678                 break;
6679             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
6680                 *eLevel = OMX_VIDEO_AVCLevel41;
6681                 break;
6682             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
6683                 *eLevel = OMX_VIDEO_AVCLevel42;
6684                 break;
6685             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
6686                 *eLevel = OMX_VIDEO_AVCLevel5;
6687                 break;
6688             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
6689                 *eLevel = OMX_VIDEO_AVCLevel51;
6690                 break;
6691             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
6692                 *eLevel = OMX_VIDEO_AVCLevel52;
6693                 break;
6694             default :
6695                 *eLevel = OMX_VIDEO_AVCLevelMax;
6696                 status = false;
6697                 break;
6698         }
6699     }
6700     else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6701         switch (codec_profile.profile) {
6702             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6703                 *eProfile = OMX_VIDEO_VP8ProfileMain;
6704                 break;
6705             default:
6706                 *eProfile = OMX_VIDEO_VP8ProfileMax;
6707                 status = false;
6708                 break;
6709         }
6710         if (!status) {
6711             return status;
6712         }
6713 
6714         switch (profile_level.level) {
6715             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6716                 *eLevel = OMX_VIDEO_VP8Level_Version0;
6717                 break;
6718             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6719                 *eLevel = OMX_VIDEO_VP8Level_Version1;
6720                 break;
6721             default:
6722                 *eLevel = OMX_VIDEO_VP8LevelMax;
6723                 status = false;
6724                 break;
6725         }
6726     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6727         switch (codec_profile.profile) {
6728             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6729                 *eProfile = OMX_VIDEO_HEVCProfileMain;
6730                 break;
6731             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6732                 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6733                 break;
6734             default:
6735                 *eProfile = OMX_VIDEO_HEVCProfileMax;
6736                 status = false;
6737                 break;
6738         }
6739         if (!status) {
6740             return status;
6741         }
6742 
6743         switch (profile_level.level) {
6744             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
6745                 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
6746                 break;
6747             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
6748                 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
6749                 break;
6750             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
6751                 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
6752                 break;
6753             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
6754                 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
6755                 break;
6756             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
6757                 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
6758                 break;
6759             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
6760                 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
6761                 break;
6762             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
6763                 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
6764                 break;
6765             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
6766                 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
6767                 break;
6768             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
6769                 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
6770                 break;
6771             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
6772                 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
6773                 break;
6774             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
6775                 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
6776                 break;
6777             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
6778                 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
6779                 break;
6780             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
6781                 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
6782                 break;
6783             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
6784                 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
6785                 break;
6786             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
6787                 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
6788                 break;
6789             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
6790                 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
6791                 break;
6792             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
6793                 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
6794                 break;
6795             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
6796                 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
6797                 break;
6798             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
6799                 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
6800                 break;
6801             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
6802                 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
6803                 break;
6804             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
6805                 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
6806                 break;
6807             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
6808                 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
6809                 break;
6810             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
6811                 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
6812                 break;
6813             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
6814                 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
6815                 break;
6816             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
6817                 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
6818                 break;
6819             default:
6820                 *eLevel = OMX_VIDEO_HEVCLevelMax;
6821                 status = false;
6822                 break;
6823         }
6824     }
6825 
6826     return status;
6827 }
6828 
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6829 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
6830 {
6831     OMX_U32 new_profile = 0, new_level = 0;
6832     unsigned const int *profile_tbl = NULL;
6833     OMX_U32 mb_per_frame, mb_per_sec;
6834     bool profile_level_found = false;
6835 
6836     DEBUG_PRINT_LOW("Init profile table for respective codec");
6837 
6838     //validate the ht,width,fps,bitrate and set the appropriate profile and level
6839     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6840         if (*eProfile == 0) {
6841             if (!m_profile_set) {
6842                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6843             } else {
6844                 switch (codec_profile.profile) {
6845                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6846                         *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6847                         break;
6848                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6849                         *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6850                         break;
6851                     default:
6852                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6853                         return false;
6854                 }
6855             }
6856         }
6857 
6858         if (*eLevel == 0 && !m_level_set) {
6859             *eLevel = OMX_VIDEO_MPEG4LevelMax;
6860         }
6861 
6862         if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
6863             profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
6864         } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
6865             profile_tbl = (unsigned int const *)
6866                 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
6867         } else {
6868             DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
6869             return false;
6870         }
6871     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6872         if (*eProfile == 0) {
6873             if (!m_profile_set) {
6874                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6875             } else {
6876                 switch (codec_profile.profile) {
6877                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6878                         *eProfile = OMX_VIDEO_AVCProfileBaseline;
6879                         break;
6880                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6881                         *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6882                         break;
6883                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6884                          *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6885                         break;
6886                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6887                         *eProfile = OMX_VIDEO_AVCProfileMain;
6888                         break;
6889                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6890                         *eProfile = OMX_VIDEO_AVCProfileExtended;
6891                         break;
6892                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6893                         *eProfile = OMX_VIDEO_AVCProfileHigh;
6894                         break;
6895                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6896                         *eProfile = OMX_VIDEO_AVCProfileHigh10;
6897                         break;
6898                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6899                         *eProfile = OMX_VIDEO_AVCProfileHigh422;
6900                         break;
6901                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6902                         *eProfile = OMX_VIDEO_AVCProfileHigh444;
6903                         break;
6904                     default:
6905                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6906                         return false;
6907                 }
6908             }
6909         }
6910 
6911         if (*eLevel == 0 && !m_level_set) {
6912             *eLevel = OMX_VIDEO_AVCLevelMax;
6913         }
6914 
6915         if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
6916             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
6917             profile_tbl = (unsigned int const *)h264_profile_level_table;
6918         } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
6919             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
6920             profile_tbl = (unsigned int const *)
6921                 (&h264_profile_level_table[H264_HP_START]);
6922         } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
6923             profile_tbl = (unsigned int const *)
6924                 (&h264_profile_level_table[H264_MP_START]);
6925         } else {
6926             DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
6927             return false;
6928         }
6929     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6930         if (*eProfile == 0) {
6931             if (!m_profile_set) {
6932                 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6933             } else {
6934                 switch (codec_profile.profile) {
6935                     case VEN_PROFILE_H263_BASELINE:
6936                         *eProfile = OMX_VIDEO_H263ProfileBaseline;
6937                         break;
6938                     default:
6939                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6940                         return false;
6941                 }
6942             }
6943         }
6944 
6945         if (*eLevel == 0 && !m_level_set) {
6946             *eLevel = OMX_VIDEO_H263LevelMax;
6947         }
6948 
6949         if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
6950             profile_tbl = (unsigned int const *)h263_profile_level_table;
6951         } else {
6952             DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
6953             return false;
6954         }
6955     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6956         if (*eProfile == 0) {
6957             *eProfile = OMX_VIDEO_VP8ProfileMain;
6958         } else {
6959             switch (codec_profile.profile) {
6960                 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6961                     *eProfile = OMX_VIDEO_VP8ProfileMain;
6962                     break;
6963                 default:
6964                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
6965                     return false;
6966             }
6967         }
6968         if (*eLevel == 0) {
6969             switch (profile_level.level) {
6970                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6971                     *eLevel = OMX_VIDEO_VP8Level_Version0;
6972                     break;
6973                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6974                     *eLevel = OMX_VIDEO_VP8Level_Version1;
6975                     break;
6976                 default:
6977                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
6978                     return false;
6979             }
6980         }
6981         return true;
6982     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6983         if (*eProfile == 0) {
6984             if (!m_profile_set) {
6985                 *eProfile = OMX_VIDEO_HEVCProfileMain;
6986             } else {
6987                 switch (codec_profile.profile) {
6988                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6989                         *eProfile = OMX_VIDEO_HEVCProfileMain;
6990                         break;
6991                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6992                         *eProfile = OMX_VIDEO_HEVCProfileMain10;
6993                         break;
6994                     default:
6995                         DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
6996                         return false;
6997                 }
6998             }
6999         }
7000 
7001         if (*eLevel == 0 && !m_level_set) {
7002             *eLevel = OMX_VIDEO_HEVCLevelMax;
7003         }
7004 
7005         if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
7006             profile_tbl = (unsigned int const *)hevc_profile_level_table;
7007         } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
7008             profile_tbl = (unsigned int const *)
7009                 (&hevc_profile_level_table[HEVC_MAIN10_START]);
7010         } else {
7011             DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
7012             return false;
7013         }
7014     } else {
7015         DEBUG_PRINT_ERROR("Invalid codec type");
7016         return false;
7017     }
7018 
7019     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
7020         ((m_sVenc_cfg.dvs_width + 15)>> 4);
7021 
7022     if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
7023         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
7024             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7025 
7026         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
7027             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7028 
7029         {
7030             new_level = profile_level.level;
7031             new_profile = codec_profile.profile;
7032             return true;
7033         }
7034     }
7035 
7036     if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
7037         *eLevel = rc_off_level; //No level calculation for RC_OFF
7038         profile_level_found = true;
7039         return true;
7040     }
7041 
7042     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
7043 
7044     bool h264, ltr, hlayers;
7045     unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
7046     h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
7047     ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7048     hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
7049      ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
7050 
7051     /*  Hybrid HP reference buffers:
7052         layers = 1, 2 need 1 reference buffer
7053         layers = 3, 4 need 2 reference buffers
7054         layers = 5, 6 need 3 reference buffers
7055     */
7056 
7057     if(hier_layers.hier_mode == HIER_P_HYBRID)
7058         hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
7059 
7060     do {
7061         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
7062             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
7063                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
7064                     if (h264 && (ltr || hlayers || hybridp)) {
7065                         // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
7066                         new_level = (int)profile_tbl[3];
7067                         new_profile = (int)profile_tbl[4];
7068                         profile_level_found = true;
7069                         DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
7070                                         ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
7071                                         MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7072                         break;
7073                     } else {
7074                         new_level = (int)profile_tbl[3];
7075                         new_profile = (int)profile_tbl[4];
7076                         profile_level_found = true;
7077                         DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
7078                         break;
7079                     }
7080                 }
7081             }
7082         }
7083         profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
7084     } while (profile_tbl[0] != 0);
7085 
7086     if (profile_level_found != true) {
7087         DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
7088         return false;
7089     }
7090 
7091     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
7092             || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
7093             || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
7094         *eLevel = new_level;
7095     }
7096 
7097     DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
7098             "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
7099 
7100     return true;
7101 }
7102 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)7103 bool venc_dev::venc_set_meta_mode(bool mode)
7104 {
7105     metadatamode = mode;
7106     return true;
7107 }
7108 #endif
7109 
venc_is_video_session_supported(unsigned long width,unsigned long height)7110 bool venc_dev::venc_is_video_session_supported(unsigned long width,
7111         unsigned long height)
7112 {
7113     if ((width * height < capability.min_width *  capability.min_height) ||
7114             (width * height > capability.max_width *  capability.max_height)) {
7115         DEBUG_PRINT_ERROR(
7116                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
7117                 width, height, capability.min_width, capability.min_height,
7118                 capability.max_width, capability.max_height);
7119         return false;
7120     }
7121 
7122     DEBUG_PRINT_LOW("video session supported");
7123     return true;
7124 }
7125 
venc_set_batch_size(OMX_U32 batchSize)7126 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
7127 {
7128     struct v4l2_control control;
7129     int ret;
7130 
7131     control.id = V4L2_CID_VIDC_QBUF_MODE;
7132     control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
7133 
7134     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
7135     if (ret) {
7136         DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
7137         return false;
7138     }
7139 
7140     mBatchSize = batchSize;
7141     DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
7142     return true;
7143 }
7144 
BatchInfo()7145 venc_dev::BatchInfo::BatchInfo()
7146     : mNumPending(0) {
7147     pthread_mutex_init(&mLock, NULL);
7148     for (int i = 0; i < kMaxBufs; ++i) {
7149         mBufMap[i] = kBufIDFree;
7150     }
7151 }
7152 
registerBuffer(int bufferId)7153 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
7154     pthread_mutex_lock(&mLock);
7155     int availId = 0;
7156     for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
7157     if (availId >= kMaxBufs) {
7158         DEBUG_PRINT_ERROR("Failed to find free entry !");
7159         pthread_mutex_unlock(&mLock);
7160         return -1;
7161     }
7162     mBufMap[availId] = bufferId;
7163     mNumPending++;
7164     pthread_mutex_unlock(&mLock);
7165     return availId;
7166 }
7167 
retrieveBufferAt(int v4l2Id)7168 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
7169     pthread_mutex_lock(&mLock);
7170     if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
7171         DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
7172         pthread_mutex_unlock(&mLock);
7173         return -1;
7174     }
7175     if (mBufMap[v4l2Id] == kBufIDFree) {
7176         DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
7177         pthread_mutex_unlock(&mLock);
7178         return -1;
7179     }
7180     int bufferId = mBufMap[v4l2Id];
7181     mBufMap[v4l2Id] = kBufIDFree;
7182     mNumPending--;
7183     pthread_mutex_unlock(&mLock);
7184     return bufferId;
7185 }
7186 
isPending(int bufferId)7187 bool venc_dev::BatchInfo::isPending(int bufferId) {
7188     pthread_mutex_lock(&mLock);
7189     int existsId = 0;
7190     for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
7191     pthread_mutex_unlock(&mLock);
7192     return existsId < kMaxBufs;
7193 }
7194 
getFdAt(native_handle_t * hnd,int index)7195 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
7196     int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
7197     return fd;
7198 }
7199 
getOffsetAt(native_handle_t * hnd,int index)7200 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
7201     int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
7202     return off;
7203 }
7204 
getSizeAt(native_handle_t * hnd,int index)7205 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
7206     int size = hnd && (index + hnd->numFds) < hnd->numInts ?
7207             hnd->data[2*hnd->numFds + index] : -1;
7208     return size;
7209 }
7210 
getColorFormatAt(native_handle_t * hnd,int index)7211 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
7212     int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
7213             hnd->data[3*hnd->numFds + index] : 0;
7214     return usage;
7215 }
7216 
getTimeStampAt(native_handle_t * hnd,int index)7217 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
7218     int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
7219             hnd->data[4*hnd->numFds + index] : -1;
7220     return size;
7221 }
7222 
7223 #ifdef _VQZIP_
venc_dev_vqzip()7224 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
7225 {
7226     mLibHandle = NULL;
7227     pthread_mutex_init(&lock, NULL);
7228 }
7229 
init()7230 bool venc_dev::venc_dev_vqzip::init()
7231 {
7232     bool status = true;
7233     if (mLibHandle) {
7234         DEBUG_PRINT_ERROR("VQZIP init called twice");
7235         status = false;
7236     }
7237     if (status) {
7238         mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
7239         if (mLibHandle) {
7240             mVQZIPInit = (vqzip_init_t)
7241                 dlsym(mLibHandle,"VQZipInit");
7242             mVQZIPDeInit = (vqzip_deinit_t)
7243                 dlsym(mLibHandle,"VQZipDeInit");
7244             mVQZIPComputeStats = (vqzip_compute_stats_t)
7245                 dlsym(mLibHandle,"VQZipComputeStats");
7246             if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
7247                 status = false;
7248         } else {
7249             DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
7250             status = false;
7251         }
7252         if (status) {
7253             mVQZIPHandle = mVQZIPInit();
7254         }
7255     }
7256     if (!status && mLibHandle) {
7257         dlclose(mLibHandle);
7258         mLibHandle = NULL;
7259         mVQZIPHandle = NULL;
7260         mVQZIPInit = NULL;
7261         mVQZIPDeInit = NULL;
7262         mVQZIPComputeStats = NULL;
7263     }
7264     return status;
7265 }
7266 
fill_stats_data(void * pBuf,void * extraData)7267 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
7268 {
7269     VQZipStatus result;
7270     VQZipStats *pStats = (VQZipStats *)extraData;
7271     pConfig.pSEIPayload = NULL;
7272     unsigned long size;
7273 
7274     if (!pBuf || !pStats || !mVQZIPHandle) {
7275         DEBUG_PRINT_ERROR("Invalid data passed to stats function");
7276     }
7277     result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
7278     return (result < 0);
7279 }
7280 
deinit()7281 void venc_dev::venc_dev_vqzip::deinit()
7282 {
7283     if (mLibHandle) {
7284         pthread_mutex_lock(&lock);
7285         dlclose(mLibHandle);
7286         mVQZIPDeInit(mVQZIPHandle);
7287         mLibHandle = NULL;
7288         mVQZIPHandle = NULL;
7289         mVQZIPInit = NULL;
7290         mVQZIPDeInit = NULL;
7291         mVQZIPComputeStats = NULL;
7292         pthread_mutex_unlock(&lock);
7293     }
7294 }
7295 
~venc_dev_vqzip()7296 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
7297 {
7298     DEBUG_PRINT_HIGH("Destroy C2D instance");
7299     if (mLibHandle) {
7300         dlclose(mLibHandle);
7301     }
7302     mLibHandle = NULL;
7303     pthread_mutex_destroy(&lock);
7304 }
7305 #endif
7306 
encExtradata(class omx_venc * venc_handle)7307 encExtradata::encExtradata(class omx_venc *venc_handle)
7308 {
7309     mCount = 0;
7310     mSize = 0;
7311     mUaddr = NULL;
7312     memset(&mIon, -1, sizeof(struct venc_ion));
7313     memset(mIndex, 0, sizeof(mIndex));
7314     mVencHandle = venc_handle;
7315     mDbgEtbCount = 0;
7316     pthread_mutex_init(&lock, NULL);
7317     vqzip_sei_found = false;
7318 }
7319 
~encExtradata()7320 encExtradata::~encExtradata()
7321 {
7322     __free();
7323     mCount = 0;
7324     mSize = 0;
7325     mVencHandle = NULL;
7326     pthread_mutex_destroy(&lock);
7327 }
7328 
__allocate()7329 OMX_ERRORTYPE encExtradata::__allocate()
7330 {
7331     ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
7332     if (!mVencHandle) {
7333         return OMX_ErrorInsufficientResources;
7334     }
7335     if (mUaddr || !totalSize) {
7336         return OMX_ErrorNone;
7337     }
7338     mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
7339             totalSize,
7340             &mIon.ion_alloc_data,
7341             &mIon.fd_ion_data, 0);
7342     if (mIon.ion_device_fd < 0) {
7343         DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
7344         DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
7345         return OMX_ErrorInsufficientResources;
7346     }
7347     mUaddr = (char *)mmap(NULL, totalSize,
7348             PROT_READ|PROT_WRITE, MAP_SHARED,
7349             mIon.fd_ion_data.fd , 0);
7350     if (mUaddr == MAP_FAILED) {
7351         DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
7352         close(mIon.fd_ion_data.fd);
7353         mVencHandle->free_ion_memory(&mIon);
7354         return OMX_ErrorInsufficientResources;
7355     }
7356     for (unsigned i = 0; i < mCount; i++) {
7357         mIndex[i].status = FREE;
7358         mIndex[i].cookie = NULL;
7359     }
7360     return OMX_ErrorNone;
7361 }
7362 
__get(char ** userptr,int * fd,unsigned * offset,ssize_t * size,int type)7363 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
7364 {
7365     unsigned i = 0;
7366     if (__allocate() != OMX_ErrorNone) {
7367         return -1;
7368     }
7369     for (i = 0; i < mCount; i++) {
7370         if (mIndex[i].status == type) {
7371             mIndex[i].status = BUSY;
7372             break;
7373         }
7374     }
7375     if (i >= mCount) {
7376         DEBUG_PRINT_HIGH("No Free extradata available");
7377         return -1;
7378     }
7379     *userptr = mUaddr + i * mSize;
7380     *fd = mIon.fd_ion_data.fd;
7381     *offset = i * mSize;
7382     *size = mSize;
7383     return i;
7384 }
7385 
get(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7386 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
7387     int index;
7388     *userptr = NULL;
7389     *fd = -1;
7390     *offset = 0;
7391     *size = 0;
7392     pthread_mutex_lock(&lock);
7393     index = __get(userptr, fd, offset, size, FREE);
7394     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7395     pthread_mutex_unlock(&lock);
7396     return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
7397 }
7398 
get(void * cookie,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7399 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
7400 {
7401     OMX_ERRORTYPE rc = OMX_ErrorNone;
7402     unsigned int i;
7403     *userptr = NULL;
7404     *fd = -1;
7405     *offset = 0;
7406     *size = 0;
7407     pthread_mutex_lock(&lock);
7408     for (i = 0; i < mCount; i++) {
7409         if (mIndex[i].cookie == cookie) {
7410             break;
7411         }
7412     }
7413     if (i < mCount) {
7414         *userptr = mUaddr + i * mSize;
7415         *fd = mIon.fd_ion_data.fd;
7416         *offset = i * mSize;
7417         *size = mSize;
7418     } else {
7419         int index = __get(userptr, fd, offset, size, FREE);
7420         if (index < 0 ) {
7421             DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
7422             __debug();
7423             rc = OMX_ErrorInsufficientResources;
7424         }
7425     }
7426     DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
7427     pthread_mutex_unlock(&lock);
7428     return rc;
7429 }
7430 
getForConfig(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7431 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
7432 {
7433     OMX_ERRORTYPE rc = OMX_ErrorNone;
7434     unsigned int i;
7435     int found = -1;
7436     pthread_mutex_lock(&lock);
7437     found = __get(userptr, fd, offset, size, FOR_CONFIG);
7438     if (found < 0) {
7439         found = __get(userptr, fd, offset, size, FREE);
7440     }
7441 
7442     if (found < 0) {
7443         DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
7444         __debug();
7445         rc = OMX_ErrorInsufficientResources;
7446     } else {
7447         mIndex[found].status = FOR_CONFIG;
7448         DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
7449     }
7450     pthread_mutex_unlock(&lock);
7451     return rc;
7452 }
7453 
put(char * userptr)7454 OMX_ERRORTYPE encExtradata::put(char *userptr)
7455 {
7456     OMX_ERRORTYPE rc = OMX_ErrorNone;
7457     int index = (userptr - mUaddr)/mSize;
7458     pthread_mutex_lock(&lock);
7459     if (!userptr) {
7460         DEBUG_PRINT_HIGH("Userptr is NULL");
7461         rc = OMX_ErrorBadParameter;
7462     } else if (index < 0) {
7463         DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
7464         __debug();
7465         rc = OMX_ErrorBadParameter;
7466     } else {
7467         mIndex[index].status = FREE;
7468         mIndex[index].cookie = NULL;
7469         DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
7470     }
7471     pthread_mutex_unlock(&lock);
7472     return rc;
7473 }
7474 
peek(unsigned index,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7475 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
7476 {
7477     OMX_ERRORTYPE rc = OMX_ErrorNone;
7478     *userptr = 0;
7479     *fd = -1;
7480     *offset = 0;
7481     *size = 0;
7482     pthread_mutex_lock(&lock);
7483     if (index < mCount) {
7484         rc = __allocate();
7485         if (rc == OMX_ErrorNone) {
7486             *userptr = mUaddr + index * mSize;
7487             *fd = mIon.fd_ion_data.fd;
7488             *offset = index * mSize;
7489             *size = mSize;
7490         }
7491     }
7492     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7493     pthread_mutex_unlock(&lock);
7494     return rc;
7495 }
7496 
setCookieForConfig(void * cookie)7497 void encExtradata::setCookieForConfig(void *cookie)
7498 {
7499     char *userptr;
7500     int fd;
7501     unsigned offset;
7502     ssize_t size;
7503     pthread_mutex_lock(&lock);
7504     int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
7505     if (found >= 0) {
7506         mIndex[found].cookie = cookie;
7507     } else {
7508         DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
7509             found, cookie);
7510         __debug();
7511     }
7512     mDbgEtbCount++;
7513     pthread_mutex_unlock(&lock);
7514 }
7515 
__free()7516 void encExtradata::__free()
7517 {
7518     ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
7519     if (mUaddr) {
7520         munmap((void *)mUaddr, totalSize);
7521         mUaddr = NULL;
7522     }
7523     if (mIon.fd_ion_data.fd >= 0) {
7524         if (mVencHandle)
7525             mVencHandle->free_ion_memory(&mIon);
7526         close(mIon.fd_ion_data.fd);
7527         mIon.fd_ion_data.fd = -1;
7528     }
7529     for (unsigned i = 0; i < mCount; i++) {
7530         mIndex[i].status = FREE;
7531         mIndex[i].cookie = NULL;
7532     }
7533 }
7534 
update(unsigned int count,ssize_t size)7535 void encExtradata::update(unsigned int count, ssize_t size)
7536 {
7537     pthread_mutex_lock(&lock);
7538     __free();
7539     mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
7540     mSize = size;
7541     DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
7542     pthread_mutex_unlock(&lock);
7543 }
7544 
__debug()7545 void encExtradata::__debug()
7546 {
7547     DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
7548             this, mCount, mSize, mUaddr, mVencHandle);
7549     for (unsigned i = 0; i < mCount; i++) {
7550         DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
7551     }
7552 }
7553 
getBufferSize()7554 ssize_t encExtradata::getBufferSize()
7555 {
7556     return mSize;
7557 }
7558 
getBufferCount()7559 unsigned int encExtradata::getBufferCount()
7560 {
7561     return mCount;
7562 }
7563