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) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1863                             if (pParam->nBFrames) {
1864                                 bFrames = pParam->nBFrames;
1865                             }
1866                         } else {
1867                             if (pParam->nBFrames) {
1868                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1869                                 bFrames = 0;
1870                             }
1871                         }
1872                     }
1873 
1874                     if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) {
1875                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1876                         return false;
1877                     }
1878 
1879                     if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1880                         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1881                         return false;
1882                     }
1883 
1884                     if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1885                         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1886                         return false;
1887                     }
1888 
1889                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1890                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1891                         return false;
1892                     }
1893                 } else {
1894                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1895                 }
1896 
1897                 //TBD, lot of other variables to be updated, yet to decide
1898                 break;
1899             }
1900         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1901             {
1902                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1903                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1904                 rc_off_level = (int)pParam->eLevel;
1905                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1906                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1907                                         pParam->eProfile, pParam->eLevel);
1908                     return false;
1909                 }
1910                 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1911                     DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1912                     return false;
1913                  }
1914                 if(!venc_set_ltrmode(1, 1)) {
1915                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1916                    return false;
1917                 }
1918 
1919                  // For VP8, hier-p and ltr are mutually exclusive features in firmware
1920                  // Disable hier-p if ltr is enabled.
1921                  if (m_codec == OMX_VIDEO_CodingVP8) {
1922                      DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1923                      if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1924                         DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1925                      }
1926                  }
1927 
1928                 break;
1929             }
1930             case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1931             {
1932                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1933                 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1934                 rc_off_level = (int)pParam->eLevel;
1935                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1936                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1937                                         pParam->eProfile, pParam->eLevel);
1938                     return false;
1939                 }
1940                 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1941                     DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1942 
1943                 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1944                 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1945                 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1946                     DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1947                     return false;
1948                 }
1949                 break;
1950             }
1951         case OMX_IndexParamVideoIntraRefresh:
1952             {
1953                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1954                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1955                     (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1956 
1957                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1958                     if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1959                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1960                         return false;
1961                     }
1962                 } else {
1963                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1964                 }
1965 
1966                 break;
1967             }
1968         case OMX_IndexParamVideoErrorCorrection:
1969             {
1970                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1971                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1972                     (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1973 
1974                 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1975                     if (venc_set_error_resilience(error_resilience) == false) {
1976                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1977                         return false;
1978                     }
1979                 } else {
1980                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1981                 }
1982 
1983                 break;
1984             }
1985         case OMX_IndexParamVideoProfileLevelCurrent:
1986             {
1987                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1988                 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1989                     (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1990 
1991                 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1992                     m_profile_set = false;
1993                     m_level_set = false;
1994                     rc_off_level = (int)profile_level->eLevel;
1995                     if (!venc_set_profile_level (profile_level->eProfile,
1996                                 profile_level->eLevel)) {
1997                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1998                         return false;
1999                     }
2000                 } else {
2001                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
2002                 }
2003 
2004                 break;
2005             }
2006         case OMX_IndexParamVideoQuantization:
2007             {
2008                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
2009                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
2010                     (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
2011                 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2012                     if (venc_set_session_qp (session_qp->nQpI,
2013                                 session_qp->nQpP,
2014                                 session_qp->nQpB) == false) {
2015                         DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
2016                         return false;
2017                     }
2018                 } else {
2019                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
2020                 }
2021 
2022                 break;
2023             }
2024         case QOMX_IndexParamVideoInitialQp:
2025             {
2026                 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
2027                     (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
2028                  if (initqp->bEnableInitQp) {
2029                     DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
2030                     if(venc_enable_initial_qp(initqp) == false) {
2031                        DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
2032                        return OMX_ErrorUnsupportedSetting;
2033                      }
2034                  } else
2035                     DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
2036                 break;
2037             }
2038         case OMX_QcomIndexParamVideoQPRange:
2039             {
2040                 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
2041                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
2042                     (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
2043 
2044                 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2045                     if(venc_set_session_qp_range (session_qp_range->minQP,
2046                                 session_qp_range->maxQP) == false) {
2047                         DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
2048                             (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
2049                         return false;
2050                     } else {
2051                         session_qp_values.minqp = session_qp_range->minQP;
2052                         session_qp_values.maxqp = session_qp_range->maxQP;
2053                     }
2054                 } else {
2055                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
2056                 }
2057 
2058                 break;
2059             }
2060         case OMX_QcomIndexEnableSliceDeliveryMode:
2061             {
2062                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
2063                     (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
2064 
2065                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2066                     if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
2067                         DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
2068                         return OMX_ErrorUnsupportedSetting;
2069                     }
2070                 } else {
2071                     DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
2072                             "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
2073                     return OMX_ErrorBadPortIndex;
2074                 }
2075 
2076                 break;
2077             }
2078         case OMX_ExtraDataFrameDimension:
2079             {
2080                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
2081                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2082 
2083                 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
2084                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
2085                     return false;
2086                 }
2087 
2088                 extradata = true;
2089                 break;
2090             }
2091         case OMX_ExtraDataVideoEncoderSliceInfo:
2092             {
2093                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
2094                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2095 
2096                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
2097                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
2098                     return false;
2099                 }
2100 
2101                 extradata = true;
2102                 break;
2103             }
2104         case OMX_ExtraDataVideoEncoderMBInfo:
2105             {
2106                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
2107                 OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
2108 
2109                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
2110                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
2111                     return false;
2112                 }
2113 
2114                 extradata = true;
2115                 break;
2116             }
2117         case OMX_QcomIndexParamSequenceHeaderWithIDR:
2118             {
2119                 PrependSPSPPSToIDRFramesParams * pParam =
2120                     (PrependSPSPPSToIDRFramesParams *)paramData;
2121 
2122                 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
2123                 if(venc_set_inband_video_header(pParam->bEnable) == false) {
2124                     DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
2125                     return OMX_ErrorUnsupportedSetting;
2126                 }
2127 
2128                 break;
2129             }
2130         case OMX_QcomIndexParamH264AUDelimiter:
2131             {
2132                 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
2133                     (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
2134 
2135                 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
2136                 if(venc_set_au_delimiter(pParam->bEnable) == false) {
2137                     DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
2138                     return OMX_ErrorUnsupportedSetting;
2139                 }
2140 
2141                 break;
2142             }
2143         case OMX_QcomIndexParamMBIStatisticsMode:
2144             {
2145                 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
2146                     (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
2147 
2148                 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
2149                 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
2150                     DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
2151                     return OMX_ErrorUnsupportedSetting;
2152                 }
2153 
2154                 break;
2155             }
2156 
2157         case OMX_QcomIndexConfigH264EntropyCodingCabac:
2158             {
2159                 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
2160                     (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
2161 
2162                 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
2163                 if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
2164                     DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
2165                     return OMX_ErrorUnsupportedSetting;
2166                 }
2167 
2168                 break;
2169             }
2170 
2171          case OMX_QcomIndexHierarchicalStructure:
2172            {
2173                QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
2174                    (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
2175 
2176                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2177                     if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
2178                         DEBUG_PRINT_ERROR("Setting Hier P count failed");
2179                         return false;
2180                     }
2181                 } else {
2182                     DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
2183                     return false;
2184                 }
2185 
2186                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
2187                 // Disable ltr if hier-p is enabled.
2188                 if (m_codec == OMX_VIDEO_CodingVP8) {
2189                     DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
2190                     if(!venc_set_ltrmode(0, 1)) {
2191                          DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
2192                      }
2193                 }
2194                 break;
2195            }
2196         case OMX_QcomIndexParamPerfLevel:
2197             {
2198                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
2199                         (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
2200                 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
2201                 if (!venc_set_perf_level(pParam->ePerfLevel)) {
2202                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
2203                     return false;
2204                 } else {
2205                     performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
2206                 }
2207                 break;
2208             }
2209         case OMX_QcomIndexParamH264VUITimingInfo:
2210             {
2211                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
2212                         (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
2213                 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
2214                 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
2215                     DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
2216                     return false;
2217                 } else {
2218                     vui_timing_info.enabled = (unsigned int) pParam->bEnable;
2219                 }
2220                 break;
2221             }
2222         case OMX_QTIIndexParamVQZIPSEIType:
2223             {
2224                 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
2225                         (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
2226                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
2227                 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
2228                     DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
2229                     return false;
2230                 }
2231                 break;
2232             }
2233         case OMX_QcomIndexParamPeakBitrate:
2234             {
2235                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
2236                         (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
2237                 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
2238                 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
2239                     DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
2240                     return false;
2241                 } else {
2242                     peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
2243                 }
2244                 break;
2245             }
2246        case OMX_QcomIndexParamSetMVSearchrange:
2247             {
2248                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
2249                is_searchrange_set = true;
2250                if (!venc_set_searchrange()) {
2251                    DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
2252                    return false;
2253                }
2254             }
2255             break;
2256         case OMX_QcomIndexParamVideoLTRCount:
2257             {
2258                 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
2259                 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
2260                         (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
2261                 if (pParam->nCount > 0) {
2262                     if (venc_set_ltrmode(1, pParam->nCount) == false) {
2263                         DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
2264                         return false;
2265                     }
2266                 } else {
2267                     if (venc_set_ltrmode(0, 0) == false) {
2268                         DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
2269                         return false;
2270                     }
2271                 }
2272                 break;
2273             }
2274         case OMX_QcomIndexParamVideoHybridHierpMode:
2275             {
2276                 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
2277                      DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
2278                      return false;
2279                 }
2280                 break;
2281             }
2282         case OMX_QcomIndexParamBatchSize:
2283             {
2284                 OMX_PARAM_U32TYPE* pParam =
2285                     (OMX_PARAM_U32TYPE*)paramData;
2286 
2287                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2288                     DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
2289                             " on output port");
2290                     return OMX_ErrorUnsupportedSetting;
2291                 }
2292 
2293                 if (!venc_set_batch_size(pParam->nU32)) {
2294                      DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
2295                      return OMX_ErrorUnsupportedSetting;
2296                 }
2297                 break;
2298             }
2299         case OMX_QcomIndexParamVencAspectRatio:
2300             {
2301                 if (!venc_set_aspectratio(paramData)) {
2302                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
2303                     return OMX_ErrorUnsupportedSetting;
2304                 }
2305                 break;
2306             }
2307         case OMX_QTIIndexParamVideoEnableRoiInfo:
2308             {
2309                 struct v4l2_control control;
2310                 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
2311                         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
2312                     DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
2313                     return OMX_ErrorUnsupportedSetting;
2314                 }
2315                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2316                 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
2317                 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
2318                 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2319                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
2320                     return OMX_ErrorUnsupportedSetting;
2321                 }
2322                 break;
2323             }
2324         case OMX_IndexParamAndroidVideoTemporalLayering:
2325             {
2326                 if (venc_set_temporal_layers(
2327                         (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
2328                     DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
2329                     return false;
2330                 }
2331                 break;
2332             }
2333         case OMX_QTIIndexParamEnableAVTimerTimestamps:
2334             {
2335                 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
2336                 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
2337                 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
2338                 break;
2339             }
2340         case OMX_IndexParamVideoSliceFMO:
2341         default:
2342             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
2343                     index);
2344             break;
2345             //case
2346     }
2347 
2348     return true;
2349 }
2350 
venc_check_valid_config()2351 bool venc_dev::venc_check_valid_config()
2352 {
2353    if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
2354        ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
2355        (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
2356         DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
2357         DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
2358         DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
2359         return false;
2360     }
2361    return true;
2362 }
2363 
venc_set_config(void * configData,OMX_INDEXTYPE index)2364 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
2365 {
2366 
2367     DEBUG_PRINT_LOW("Inside venc_set_config");
2368 
2369     if(!venc_check_valid_config()) {
2370         DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
2371         return false;
2372     }
2373 
2374     switch ((int)index) {
2375         case OMX_IndexConfigVideoBitrate:
2376             {
2377                 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
2378                     configData;
2379                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
2380 
2381                 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2382                     if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
2383                         DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
2384                         return false;
2385                     }
2386                 } else {
2387                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
2388                 }
2389 
2390                 break;
2391             }
2392         case OMX_IndexConfigVideoFramerate:
2393             {
2394                 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
2395                     configData;
2396                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
2397 
2398                 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2399                     if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
2400                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2401                         return false;
2402                     }
2403                 } else {
2404                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2405                 }
2406 
2407                 break;
2408             }
2409         case QOMX_IndexConfigVideoIntraperiod:
2410             {
2411                 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
2412                 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
2413                     (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
2414 
2415                 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2416                     if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
2417                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
2418                         return false;
2419                     }
2420                 }
2421 
2422                 break;
2423             }
2424         case OMX_IndexConfigVideoIntraVOPRefresh:
2425             {
2426                 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
2427                     configData;
2428                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
2429 
2430                 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2431                     if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2432                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2433                         return false;
2434                     }
2435                 } else {
2436                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2437                 }
2438 
2439                 break;
2440             }
2441         case OMX_IndexConfigCommonRotate:
2442             {
2443                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2444                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2445                 OMX_U32 nFrameWidth;
2446                 if (!config_rotation) {
2447                    return false;
2448                 }
2449                 if (true == deinterlace_enabled) {
2450                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2451                     return false;
2452                 }
2453                 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2454                 nFrameWidth = m_sVenc_cfg.dvs_width;
2455                 m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
2456                 m_sVenc_cfg.dvs_height = nFrameWidth;
2457 
2458                 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2459                     DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2460                     return false;
2461                 }
2462 
2463                 break;
2464             }
2465         case OMX_IndexConfigVideoAVCIntraPeriod:
2466             {
2467                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2468                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2469 
2470                 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2471                         == false) {
2472                     DEBUG_PRINT_ERROR("ERROR: Setting "
2473                             "OMX_IndexConfigVideoAVCIntraPeriod failed");
2474                     return false;
2475                 }
2476                 break;
2477             }
2478         case OMX_IndexConfigCommonDeinterlace:
2479             {
2480                 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2481                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2482                 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2483                     if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2484                         m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2485                     {
2486                         DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2487                         return false;
2488                     }
2489                     if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2490                         DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2491                         return false;
2492                     }
2493                 } else {
2494                 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2495                 }
2496                 break;
2497             }
2498         case OMX_IndexConfigVideoVp8ReferenceFrame:
2499             {
2500                 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2501                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2502                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2503                         (vp8refframe->bUseGoldenFrame)) {
2504                     if(venc_set_useltr(0x1) == false) {
2505                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2506                         return false;
2507                     }
2508                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2509                         (vp8refframe->bGoldenFrameRefresh)) {
2510                     if(venc_set_markltr(0x1) == false) {
2511                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2512                         return false;
2513                     }
2514                 } else {
2515                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2516                 }
2517                 break;
2518             }
2519         case OMX_QcomIndexConfigVideoLTRUse:
2520             {
2521                 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2522                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2523                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2524                     if (venc_set_useltr(pParam->nID) == false) {
2525                         DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2526                         return false;
2527                     }
2528                 } else {
2529                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2530                 }
2531                 break;
2532             }
2533         case OMX_QcomIndexConfigVideoLTRMark:
2534             {
2535                 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2536                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2537                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2538                     if (venc_set_markltr(pParam->nID) == false) {
2539                         DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2540                         return false;
2541                     }
2542                 }  else {
2543                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2544                 }
2545                 break;
2546             }
2547         case OMX_QcomIndexConfigPerfLevel:
2548             {
2549                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2550                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2551                 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2552                 if (!venc_set_perf_level(perf->ePerfLevel)) {
2553                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2554                     return false;
2555                 } else {
2556                     performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2557                 }
2558                 break;
2559             }
2560         case OMX_QcomIndexConfigVideoVencPerfMode:
2561             {
2562                 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2563                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2564                 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2565                     DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2566                     return false;
2567                 }
2568                 break;
2569             }
2570         case OMX_QcomIndexConfigNumHierPLayers:
2571             {
2572                 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
2573                     (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
2574                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
2575                 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
2576                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
2577                     return false;
2578                 }
2579                 break;
2580             }
2581         case OMX_QcomIndexConfigBaseLayerId:
2582             {
2583                 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
2584                     (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
2585                 if (venc_set_baselayerid(pParam->nPID) == false) {
2586                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
2587                     return OMX_ErrorUnsupportedSetting;
2588                 }
2589                 break;
2590             }
2591         case OMX_IndexParamAndroidVideoTemporalLayering:
2592             {
2593                 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2594                 return false;
2595             }
2596         case OMX_QcomIndexConfigQp:
2597             {
2598                 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
2599                     (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
2600                 if (venc_set_qp(pParam->nQP) == false) {
2601                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
2602                     return OMX_ErrorUnsupportedSetting;
2603                 }
2604                 break;
2605             }
2606         case OMX_IndexConfigPriority:
2607             {
2608                 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2609                 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
2610                 if (!venc_set_priority(priority->nU32)) {
2611                     DEBUG_PRINT_ERROR("Failed to set priority");
2612                     return false;
2613                 }
2614                 sess_priority.priority = priority->nU32;
2615                 break;
2616             }
2617         case OMX_IndexConfigOperatingRate:
2618             {
2619                 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2620                 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2621                 if (!venc_set_operatingrate(rate->nU32)) {
2622                     DEBUG_PRINT_ERROR("Failed to set operating rate");
2623                     return false;
2624                 }
2625                 break;
2626             }
2627         case OMX_QTIIndexConfigVideoRoiInfo:
2628             {
2629                 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
2630                     DEBUG_PRINT_ERROR("Failed to set ROI QP info");
2631                     return false;
2632                 }
2633                 break;
2634             }
2635         case OMX_IndexConfigAndroidIntraRefresh:
2636             {
2637                 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2638                 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2639 
2640                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2641                     OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2642                     OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2643 
2644                     if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2645                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2646                         return false;
2647                     }
2648                 } else {
2649                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2650                 }
2651                 break;
2652             }
2653         case OMX_QTIIndexConfigDescribeColorAspects:
2654             {
2655                 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
2656 
2657                 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
2658                 OMX_U32 full_range = 0;
2659                 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2660                 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2661 
2662                 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
2663                     case ColorAspects::PrimariesBT709_5:
2664                         color_space = MSM_VIDC_BT709_5;
2665                         break;
2666                     case ColorAspects::PrimariesBT470_6M:
2667                         color_space = MSM_VIDC_BT470_6_M;
2668                         break;
2669                     case ColorAspects::PrimariesBT601_6_625:
2670                         color_space = MSM_VIDC_BT601_6_625;
2671                         break;
2672                     case ColorAspects::PrimariesBT601_6_525:
2673                         color_space = MSM_VIDC_BT601_6_525;
2674                         break;
2675                     case ColorAspects::PrimariesGenericFilm:
2676                         color_space = MSM_VIDC_GENERIC_FILM;
2677                         break;
2678                     case ColorAspects::PrimariesBT2020:
2679                         color_space = MSM_VIDC_BT2020;
2680                         break;
2681                     default:
2682                         color_space = MSM_VIDC_BT601_6_625;
2683                         //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2684                         break;
2685                 }
2686                 switch((ColorAspects::Range)params->sAspects.mRange) {
2687                     case ColorAspects::RangeFull:
2688                         full_range = 1;
2689                         break;
2690                     case ColorAspects::RangeLimited:
2691                         full_range = 0;
2692                         break;
2693                     default:
2694                         break;
2695                 }
2696                 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
2697                     case ColorAspects::TransferSMPTE170M:
2698                         transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
2699                         break;
2700                     case ColorAspects::TransferUnspecified:
2701                         transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
2702                         break;
2703                     case ColorAspects::TransferGamma22:
2704                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
2705                         break;
2706                     case ColorAspects::TransferGamma28:
2707                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
2708                         break;
2709                     case ColorAspects::TransferSMPTE240M:
2710                         transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
2711                         break;
2712                     case ColorAspects::TransferLinear:
2713                         transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
2714                         break;
2715                     case ColorAspects::TransferXvYCC:
2716                         transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
2717                         break;
2718                     case ColorAspects::TransferBT1361:
2719                         transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
2720                         break;
2721                     case ColorAspects::TransferSRGB:
2722                         transfer_chars = MSM_VIDC_TRANSFER_SRGB;
2723                         break;
2724                     default:
2725                         //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2726                         transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2727                         break;
2728                 }
2729                 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
2730                     case ColorAspects::MatrixUnspecified:
2731                         matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
2732                         break;
2733                     case ColorAspects::MatrixBT709_5:
2734                         matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
2735                         break;
2736                     case ColorAspects::MatrixBT470_6M:
2737                         matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
2738                         break;
2739                     case ColorAspects::MatrixBT601_6:
2740                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
2741                         break;
2742                     case ColorAspects::MatrixSMPTE240M:
2743                         transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
2744                         break;
2745                     case ColorAspects::MatrixBT2020:
2746                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
2747                         break;
2748                     case ColorAspects::MatrixBT2020Constant:
2749                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
2750                         break;
2751                     default:
2752                         //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2753                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2754                         break;
2755                 }
2756                 if (!venc_set_colorspace(color_space, full_range,
2757                             transfer_chars, matrix_coeffs)) {
2758 
2759                     DEBUG_PRINT_ERROR("Failed to set operating rate");
2760                     return false;
2761                 }
2762                 break;
2763             }
2764         default:
2765             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2766             break;
2767     }
2768 
2769     return true;
2770 }
2771 
venc_stop(void)2772 unsigned venc_dev::venc_stop( void)
2773 {
2774     struct venc_msg venc_msg;
2775     struct v4l2_requestbuffers bufreq;
2776     int rc = 0, ret = 0;
2777 
2778     if (!stopped) {
2779         enum v4l2_buf_type cap_type;
2780 
2781         if (streaming[OUTPUT_PORT]) {
2782             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2783             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2784 
2785             if (rc) {
2786                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2787                         cap_type, rc);
2788             } else
2789                 streaming[OUTPUT_PORT] = false;
2790 
2791             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2792             bufreq.memory = V4L2_MEMORY_USERPTR;
2793             bufreq.count = 0;
2794             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2795             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2796 
2797             if (ret) {
2798                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2799                 return false;
2800             }
2801         }
2802 
2803         if (!rc && streaming[CAPTURE_PORT]) {
2804             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2805             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2806 
2807             if (rc) {
2808                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2809                         cap_type, rc);
2810             } else
2811                 streaming[CAPTURE_PORT] = false;
2812 
2813             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2814             bufreq.memory = V4L2_MEMORY_USERPTR;
2815             bufreq.count = 0;
2816             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2817             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2818 
2819             if (ret) {
2820                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2821                 return false;
2822             }
2823         }
2824 
2825         if (!rc && !ret) {
2826             venc_stop_done();
2827             stopped = 1;
2828             /*set flag to re-configure when started again*/
2829             resume_in_stopped = 1;
2830 
2831         }
2832     }
2833 
2834     return rc;
2835 }
2836 
venc_pause(void)2837 unsigned venc_dev::venc_pause(void)
2838 {
2839     pthread_mutex_lock(&pause_resume_mlock);
2840     paused = true;
2841     pthread_mutex_unlock(&pause_resume_mlock);
2842     return 0;
2843 }
2844 
venc_resume(void)2845 unsigned venc_dev::venc_resume(void)
2846 {
2847     pthread_mutex_lock(&pause_resume_mlock);
2848     paused = false;
2849     pthread_mutex_unlock(&pause_resume_mlock);
2850 
2851     return pthread_cond_signal(&pause_resume_cond);
2852 }
2853 
venc_start_done(void)2854 unsigned venc_dev::venc_start_done(void)
2855 {
2856     struct venc_msg venc_msg;
2857     venc_msg.msgcode = VEN_MSG_START;
2858     venc_msg.statuscode = VEN_S_SUCCESS;
2859     venc_handle->async_message_process(venc_handle,&venc_msg);
2860     return 0;
2861 }
2862 
venc_stop_done(void)2863 unsigned venc_dev::venc_stop_done(void)
2864 {
2865     struct venc_msg venc_msg;
2866     venc_msg.msgcode=VEN_MSG_STOP;
2867     venc_msg.statuscode=VEN_S_SUCCESS;
2868     venc_handle->async_message_process(venc_handle,&venc_msg);
2869     return 0;
2870 }
2871 
venc_set_message_thread_id(pthread_t tid)2872 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2873 {
2874     async_thread_created = true;
2875     m_tid=tid;
2876     return 0;
2877 }
2878 
venc_set_vqzip_defaults()2879 bool venc_dev::venc_set_vqzip_defaults()
2880 {
2881     struct v4l2_control control;
2882     int rc = 0, num_mbs_per_frame;
2883 
2884     num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
2885 
2886     switch (num_mbs_per_frame) {
2887     case OMX_CORE_720P_WIDTH  * OMX_CORE_720P_HEIGHT:
2888     case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
2889     case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
2890     case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
2891         break;
2892     default:
2893         DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
2894             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
2895         return false;
2896     }
2897 
2898     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
2899     control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
2900     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2901     if (rc)
2902         DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
2903     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
2904     control.value = INT_MAX;
2905 
2906     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2907     if (rc)
2908         DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
2909 
2910     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
2911     control.value = 0;
2912 
2913     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2914     if (rc)
2915         DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
2916 
2917     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
2918     control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
2919 
2920     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2921     if (rc)
2922         DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
2923 
2924     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2925     control.value = 1;
2926 
2927     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2928     if (rc)
2929         DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP");
2930 
2931     return true;
2932 }
2933 
2934 
venc_start(void)2935 unsigned venc_dev::venc_start(void)
2936 {
2937     enum v4l2_buf_type buf_type;
2938     int ret, r;
2939     struct v4l2_control control;
2940 
2941     memset(&control, 0, sizeof(control));
2942 
2943     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2944             __func__);
2945     m_level_set = false;
2946 
2947     if (!venc_set_profile_level(0, 0)) {
2948         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2949                 __func__);
2950     } else {
2951         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2952                 __func__, codec_profile.profile, profile_level.level);
2953     }
2954 
2955     if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
2956         return 1;
2957 
2958     // disable B-frames for realtime high-resolution/fps usecases for power considerations
2959     if (intra_period.num_bframes &&
2960             sess_priority.priority == 0 /*realtime*/ &&
2961             (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) ||
2962             (operating_rate >= 60 << 16))) {
2963         intra_period.num_pframes += (intra_period.num_bframes + 1);
2964         intra_period.num_bframes = 0;
2965         if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
2966             DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec",
2967                     m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16);
2968         } else {
2969             DEBUG_PRINT_ERROR("Failed to disable B frames!");
2970         }
2971     }
2972 
2973     // re-configure the temporal layers as RC-mode and key-frame interval
2974     // might have changed since the client last configured the layers.
2975     if (temporal_layers_config.nPLayers) {
2976         if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2977             DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2978         } else {
2979             // request buffers on capture port again since internal (scratch)-
2980             // buffer requirements may change (i.e if we switch from non-hybrid
2981             // to hybrid mode and vice-versa)
2982             struct v4l2_requestbuffers bufreq;
2983 
2984             bufreq.memory = V4L2_MEMORY_USERPTR;
2985             bufreq.count = m_sOutput_buff_property.actualcount;
2986             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2987             if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2988                 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2989             }
2990         }
2991     }
2992 
2993     venc_config_print();
2994 
2995     if(resume_in_stopped){
2996         /*set buffercount when restarted*/
2997         venc_reconfig_reqbufs();
2998         resume_in_stopped = 0;
2999     }
3000 
3001     /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
3002     if (slice_mode.enable && multislice.mslice_size &&
3003             (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
3004         DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
3005                 (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
3006                 MAX_SUPPORTED_SLICES_PER_FRAME);
3007         return 1;
3008     }
3009 
3010     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3011     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
3012     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
3013 
3014     if (ret)
3015         return 1;
3016 
3017     streaming[CAPTURE_PORT] = true;
3018 
3019     control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
3020     control.value = 1;
3021     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3022     if (ret) {
3023         DEBUG_PRINT_ERROR("failed to request seq header");
3024         return 1;
3025     }
3026 
3027 
3028     stopped = 0;
3029     return 0;
3030 }
3031 
hiermode_string(int val)3032 inline const char* hiermode_string(int val)
3033 {
3034     switch(val)
3035     {
3036     case HIER_NONE:
3037         return "No Hier";
3038     case HIER_P:
3039         return "Hier-P";
3040     case HIER_B:
3041         return "Hier-B";
3042     case HIER_P_HYBRID:
3043         return "Hybrid Hier-P";
3044     default:
3045         return "No hier";
3046     }
3047 }
3048 
bitrate_type_string(int val)3049 inline const char* bitrate_type_string(int val)
3050 {
3051     switch(val)
3052     {
3053     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
3054         return "CUMULATIVE";
3055     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
3056         return "LAYER WISE";
3057     default:
3058         return "Unknown Bitrate Type";
3059     }
3060 }
3061 
codec_as_string(unsigned long codec)3062 static const char *codec_as_string(unsigned long codec) {
3063     switch (codec) {
3064     case V4L2_PIX_FMT_H264:
3065         return "H264";
3066     case V4L2_PIX_FMT_MPEG4:
3067         return "MPEG4";
3068     case V4L2_PIX_FMT_H263:
3069         return "H263";
3070     case V4L2_PIX_FMT_HEVC:
3071         return "HEVC";
3072     case V4L2_PIX_FMT_VP8:
3073         return "VP8";
3074     default:
3075         return "UNKOWN";
3076     }
3077 }
3078 
venc_config_print()3079 void venc_dev::venc_config_print()
3080 {
3081 
3082     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
3083             codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
3084 
3085     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
3086             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
3087             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3088 
3089     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
3090             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
3091             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3092 
3093     DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
3094             color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
3095 
3096     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
3097             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
3098 
3099     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
3100             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
3101 
3102     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
3103             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
3104 
3105     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
3106             session_qp_values.minqp, session_qp_values.maxqp);
3107 
3108     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
3109             voptimecfg.voptime_resolution, multislice.mslice_mode,
3110             multislice.mslice_size);
3111 
3112     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
3113             entropy.longentropysel, entropy.cabacmodel);
3114 
3115     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
3116             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
3117             dbkfilter.slicebeta_offset);
3118 
3119     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
3120             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
3121 
3122     DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
3123             ltrinfo.enabled, ltrinfo.count);
3124 
3125     if (temporal_layers_config.nPLayers) {
3126         DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
3127                 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
3128                 intra_period.num_pframes + intra_period.num_bframes + 1);
3129 
3130         for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
3131                 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
3132             DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
3133                     l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
3134         }
3135     } else {
3136 
3137         DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
3138                 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
3139 
3140         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
3141                 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
3142 
3143         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
3144                 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
3145                 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
3146                 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
3147     }
3148 
3149     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
3150 
3151     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
3152 
3153     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
3154 
3155     DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
3156 
3157     DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
3158 }
3159 
venc_reconfig_reqbufs()3160 bool venc_dev::venc_reconfig_reqbufs()
3161 {
3162     struct v4l2_requestbuffers bufreq;
3163 
3164     bufreq.memory = V4L2_MEMORY_USERPTR;
3165     bufreq.count = m_sInput_buff_property.actualcount;
3166     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3167     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3168             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
3169             return false;
3170     }
3171 
3172     bufreq.memory = V4L2_MEMORY_USERPTR;
3173     bufreq.count = m_sOutput_buff_property.actualcount;
3174     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3175     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
3176     {
3177             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
3178             return false;
3179     }
3180     return true;
3181 }
3182 
venc_flush(unsigned port)3183 unsigned venc_dev::venc_flush( unsigned port)
3184 {
3185     struct v4l2_encoder_cmd enc;
3186     DEBUG_PRINT_LOW("in %s", __func__);
3187 
3188     enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
3189     enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3190 
3191     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
3192         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
3193         return -1;
3194     }
3195 
3196     return 0;
3197 
3198 }
3199 
3200 //allocating I/P memory from pmem and register with the device
3201 
3202 
venc_use_buf(void * buf_addr,unsigned port,unsigned index)3203 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
3204 {
3205 
3206     struct pmem *pmem_tmp;
3207     struct v4l2_buffer buf;
3208     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3209     int rc = 0;
3210     unsigned int extra_idx;
3211 
3212     pmem_tmp = (struct pmem *)buf_addr;
3213     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
3214 
3215     if (port == PORT_INDEX_OUT) {
3216         extra_idx = EXTRADATA_IDX(num_output_planes);
3217         buf.index = index;
3218         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3219         buf.memory = V4L2_MEMORY_USERPTR;
3220         plane[0].length = pmem_tmp->size;
3221         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
3222         plane[0].reserved[0] = pmem_tmp->fd;
3223         plane[0].reserved[1] = 0;
3224         plane[0].data_offset = pmem_tmp->offset;
3225         buf.m.planes = plane;
3226         buf.length = num_output_planes;
3227 
3228         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3229             char *userptr;
3230             int fd;
3231             unsigned offset;
3232             ssize_t size;
3233             int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size);
3234             if (rc != OMX_ErrorNone) {
3235                 DEBUG_PRINT_ERROR("Unable to get extradata memory 2");
3236                 return rc;
3237             }
3238             plane[extra_idx].length = size;
3239             plane[extra_idx].m.userptr = (unsigned long)userptr;
3240 #ifdef USE_ION
3241             plane[extra_idx].reserved[0] = fd;
3242 #endif
3243             plane[extra_idx].reserved[1] = offset;
3244             plane[extra_idx].data_offset = 0;
3245         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
3246             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
3247             return OMX_ErrorBadParameter;
3248         }
3249 
3250         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
3251 
3252         if (rc)
3253             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
3254     } else if (port == PORT_INDEX_IN) {
3255             DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port");
3256     } else {
3257         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
3258         return false;
3259     }
3260 
3261     return true;
3262 }
3263 
venc_free_buf(void * buf_addr,unsigned port)3264 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
3265 {
3266     struct pmem *pmem_tmp;
3267     struct venc_bufferpayload dev_buffer;
3268 
3269     memset(&dev_buffer, 0, sizeof(dev_buffer));
3270     pmem_tmp = (struct pmem *)buf_addr;
3271 
3272     if (port == PORT_INDEX_IN) {
3273         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3274         dev_buffer.fd  = pmem_tmp->fd;
3275         dev_buffer.maped_size = pmem_tmp->size;
3276         dev_buffer.sz = pmem_tmp->size;
3277         dev_buffer.offset = pmem_tmp->offset;
3278         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3279                 dev_buffer.pbuffer, \
3280                 dev_buffer.fd, \
3281                 dev_buffer.offset, \
3282                 dev_buffer.maped_size);
3283 
3284     } else if (port == PORT_INDEX_OUT) {
3285         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3286         dev_buffer.fd  = pmem_tmp->fd;
3287         dev_buffer.sz = pmem_tmp->size;
3288         dev_buffer.maped_size = pmem_tmp->size;
3289         dev_buffer.offset = pmem_tmp->offset;
3290 
3291         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3292                 dev_buffer.pbuffer, \
3293                 dev_buffer.fd, \
3294                 dev_buffer.offset, \
3295                 dev_buffer.maped_size);
3296     } else {
3297         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
3298         return false;
3299     }
3300 
3301     return true;
3302 }
3303 
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3304 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
3305         OMX_U32 width, OMX_U32 height)
3306 {
3307     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
3308             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
3309             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
3310             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
3311             src_chroma_offset = width * height;
3312 
3313     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
3314         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3315         //Do chroma first, so that we can convert it in-place
3316         src_buf += width * height;
3317         dst_buf += y_stride * y_scanlines;
3318         for (int line = height / 2 - 1; line >= 0; --line) {
3319             memmove(dst_buf + line * uv_stride,
3320                     src_buf + line * width,
3321                     width);
3322         }
3323 
3324         dst_buf = src_buf = buffer->pBuffer;
3325         //Copy the Y next
3326         for (int line = height - 1; line > 0; --line) {
3327             memmove(dst_buf + line * y_stride,
3328                     src_buf + line * width,
3329                     width);
3330         }
3331     } else {
3332         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3333                 Insufficient bufferLen=%u v/s Required=%u",
3334                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3335                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3336         return false;
3337     }
3338 
3339     return true;
3340 }
3341 
venc_get_performance_level(OMX_U32 * perflevel)3342 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
3343 {
3344     if (!perflevel) {
3345         DEBUG_PRINT_ERROR("Null pointer error");
3346         return false;
3347     } else {
3348         *perflevel = performance_level.perflevel;
3349         return true;
3350     }
3351 }
3352 
venc_get_vui_timing_info(OMX_U32 * enabled)3353 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
3354 {
3355     if (!enabled) {
3356         DEBUG_PRINT_ERROR("Null pointer error");
3357         return false;
3358     } else {
3359         *enabled = vui_timing_info.enabled;
3360         return true;
3361     }
3362 }
3363 
venc_get_vqzip_sei_info(OMX_U32 * enabled)3364 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
3365 {
3366     if (!enabled) {
3367         DEBUG_PRINT_ERROR("Null pointer error");
3368         return false;
3369     } else {
3370         *enabled = vqzip_sei_info.enabled;
3371         return true;
3372     }
3373 }
3374 
venc_get_peak_bitrate(OMX_U32 * peakbitrate)3375 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
3376 {
3377     if (!peakbitrate) {
3378         DEBUG_PRINT_ERROR("Null pointer error");
3379         return false;
3380     } else {
3381         *peakbitrate = peak_bitrate.peakbitrate;
3382         return true;
3383     }
3384 }
3385 
venc_get_batch_size(OMX_U32 * size)3386 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
3387 {
3388     if (!size) {
3389         DEBUG_PRINT_ERROR("Null pointer error");
3390         return false;
3391     } else {
3392         *size = mBatchSize;
3393         return true;
3394     }
3395 }
3396 
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3397 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
3398 {
3399     struct pmem *temp_buffer;
3400     struct v4l2_buffer buf;
3401     struct v4l2_requestbuffers bufreq;
3402     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3403     int rc = 0, extra_idx;
3404     struct OMX_BUFFERHEADERTYPE *bufhdr;
3405     encoder_media_buffer_type * meta_buf = NULL;
3406     temp_buffer = (struct pmem *)buffer;
3407 
3408     memset (&buf, 0, sizeof(buf));
3409     memset (&plane, 0, sizeof(plane));
3410 
3411     if (buffer == NULL) {
3412         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
3413         return false;
3414     }
3415 
3416     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3417     bufreq.memory = V4L2_MEMORY_USERPTR;
3418     bufreq.count = m_sInput_buff_property.actualcount;
3419     bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3420 
3421     DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
3422 
3423     if (pmem_data_buf) {
3424         DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
3425         plane[0].m.userptr = (unsigned long)pmem_data_buf;
3426         plane[0].data_offset = bufhdr->nOffset;
3427         plane[0].length = bufhdr->nAllocLen;
3428         plane[0].bytesused = bufhdr->nFilledLen;
3429     } else {
3430         // --------------------------------------------------------------------------------------
3431         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
3432         // ---------------------------------------------------------------------------------------
3433         // Camera-2              1            CameraSource   0              meta-handle
3434         // Camera-3              1            GrallocSource  0              gralloc-private-handle
3435         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
3436         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
3437         // ---------------------------------------------------------------------------------------
3438         if (metadatamode) {
3439             plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3440             meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3441 
3442             if (!meta_buf) {
3443                 //empty EOS buffer
3444                 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
3445                     plane[0].data_offset = bufhdr->nOffset;
3446                     plane[0].length = bufhdr->nAllocLen;
3447                     plane[0].bytesused = bufhdr->nFilledLen;
3448                     DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
3449                 } else {
3450                     return false;
3451                 }
3452             } else if (!color_format) {
3453                 int usage = 0;
3454 
3455                 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3456                     native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
3457                     if (!hnd) {
3458                         DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
3459                         return false;
3460                     }
3461 
3462                     if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
3463                         usage = hnd->data[3];
3464                     } else if (mBatchSize) {
3465                         usage = BatchInfo::getColorFormatAt(hnd, 0);
3466                     }
3467                     if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
3468                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3469                     }
3470 
3471                     if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
3472                         m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
3473                         struct v4l2_format fmt;
3474 
3475                         memset(&fmt, 0, sizeof(fmt));
3476                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
3477                                 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
3478                             DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
3479                             DEBUG_PRINT_ERROR(" This leads to unknown color space");
3480                         }
3481                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
3482                             if (is_csc_enabled) {
3483                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3484                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3485                                 venc_set_colorspace(MSM_VIDC_BT709_5, 1,
3486                                         MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
3487                             } else {
3488                                 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
3489                                         MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3490                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3491                             }
3492                         }
3493                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3494                         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3495                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3496                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3497                         if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
3498                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
3499                         }
3500                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3501                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3502                             DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
3503                             return false;
3504                         }
3505                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3506                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3507                             return false;
3508                         }
3509                     }
3510 
3511                     // Setting batch mode is sticky. We do not expect camera to change
3512                     // between batch and normal modes at runtime.
3513                     if (mBatchSize) {
3514                         if ((unsigned)hnd->numFds != mBatchSize) {
3515                             DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
3516                                     mBatchSize, hnd->numFds);
3517                             return false;
3518                         }
3519 
3520                         return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
3521                     }
3522 
3523                     if (hnd->numFds + hnd->numInts > 2) {
3524                         plane[0].data_offset = hnd->data[1];
3525                         plane[0].length = hnd->data[2];
3526                         plane[0].bytesused = hnd->data[2];
3527                     }
3528                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
3529                             fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
3530                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
3531                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
3532 
3533                     if (!handle) {
3534                         DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
3535                         return false;
3536                     }
3537 
3538                     if (mUseAVTimerTimestamps) {
3539                         uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
3540                         if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
3541                                 && avTimerTimestampNs > 0) {
3542                             bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
3543                             DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
3544                         }
3545                     }
3546 
3547                     if (!streaming[OUTPUT_PORT]) {
3548                         // Moment of truth... actual colorspace is known here..
3549                         ColorSpace_t colorSpace = ITU_R_601;
3550                         if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
3551                             DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3552                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3553                         }
3554 
3555                         struct v4l2_format fmt;
3556                         memset(&fmt, 0, sizeof(fmt));
3557                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3558 
3559                         bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
3560                         if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3561                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
3562                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
3563                         } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
3564                             // In case of RGB, conversion to YUV is handled within encoder.
3565                             // Disregard the Colorspace in gralloc-handle in case of RGB and use
3566                             //   [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
3567                             //   [b] 601 for UBWC case     : Venus can convert to 601-LR or FR. use LR for now.
3568                             colorSpace = ITU_R_601;
3569                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
3570                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
3571                         } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3572                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3573                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
3574                         }
3575 
3576                         // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
3577                         if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
3578                             struct v4l2_control control;
3579                             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
3580                             control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
3581                             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3582                                 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
3583                             } else {
3584                                 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
3585                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3586                                 colorSpace = ITU_R_709;
3587                             }
3588                         }
3589 
3590                         msm_vidc_h264_color_primaries_values primary;
3591                         msm_vidc_h264_transfer_chars_values transfer;
3592                         msm_vidc_h264_matrix_coeff_values matrix;
3593                         OMX_U32 range;
3594 
3595                         switch (colorSpace) {
3596                             case ITU_R_601_FR:
3597                             {
3598                                 primary = MSM_VIDC_BT601_6_525;
3599                                 range = 1; // full
3600                                 transfer = MSM_VIDC_TRANSFER_601_6_525;
3601                                 matrix = MSM_VIDC_MATRIX_601_6_525;
3602 
3603                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3604                                 break;
3605                             }
3606                             case ITU_R_709:
3607                             {
3608                                 primary = MSM_VIDC_BT709_5;
3609                                 range = 0; // limited
3610                                 transfer = MSM_VIDC_TRANSFER_BT709_5;
3611                                 matrix = MSM_VIDC_MATRIX_BT_709_5;
3612 
3613                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3614                                 break;
3615                             }
3616                             default:
3617                             {
3618                                 // 601 or something else ? assume 601
3619                                 primary = MSM_VIDC_BT601_6_625;
3620                                 range = 0; //limited
3621                                 transfer = MSM_VIDC_TRANSFER_601_6_625;
3622                                 matrix = MSM_VIDC_MATRIX_601_6_625;
3623 
3624                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3625                                 break;
3626                             }
3627                         }
3628                         DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3629                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3630                         venc_set_colorspace(primary, range, transfer, matrix);
3631 
3632                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3633                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3634                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3635                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3636                             DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
3637                             return false;
3638                         }
3639                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3640                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3641                             return false;
3642                         }
3643                     }
3644 
3645                     fd = handle->fd;
3646                     plane[0].data_offset = 0;
3647                     plane[0].length = handle->size;
3648                     plane[0].bytesused = handle->size;
3649                     DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
3650                                 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
3651                 }
3652             } else {
3653                 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3654                 plane[0].data_offset = bufhdr->nOffset;
3655                 plane[0].length = bufhdr->nAllocLen;
3656                 plane[0].bytesused = bufhdr->nFilledLen;
3657                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
3658                         fd, plane[0].bytesused, plane[0].length);
3659             }
3660         } else {
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: non-camera buf: fd = %d filled %d of %d",
3666                     fd, plane[0].bytesused, plane[0].length);
3667         }
3668     }
3669 
3670     extra_idx = EXTRADATA_IDX(num_input_planes);
3671 
3672     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3673         char *userptr;
3674         int fd;
3675         unsigned offset;
3676         ssize_t size;
3677         int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
3678         if (rc != OMX_ErrorNone) {
3679             DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
3680             return rc;
3681         }
3682         plane[extra_idx].bytesused = 0;
3683         plane[extra_idx].length = size;
3684         plane[extra_idx].m.userptr = (unsigned long) userptr;
3685 #ifdef USE_ION
3686         plane[extra_idx].reserved[0] = fd;
3687 #endif
3688         plane[extra_idx].reserved[1] = offset;
3689         plane[extra_idx].data_offset = 0;
3690     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3691         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3692         return false;
3693     }
3694 
3695     buf.index = index;
3696     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3697     buf.memory = V4L2_MEMORY_USERPTR;
3698     plane[0].reserved[0] = fd;
3699     plane[0].reserved[1] = 0;
3700     buf.m.planes = plane;
3701     buf.length = num_input_planes;
3702 
3703     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3704         buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3705 
3706     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3707     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3708     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3709 
3710     if (rc) {
3711         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3712         return false;
3713     }
3714 
3715     etb++;
3716 
3717     if (!streaming[OUTPUT_PORT]) {
3718         enum v4l2_buf_type buf_type;
3719         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3720         int ret;
3721         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3722 
3723         if (ret) {
3724             DEBUG_PRINT_ERROR("Failed to call streamon");
3725             if (errno == EBUSY) {
3726                 hw_overload = true;
3727             }
3728             return false;
3729         } else {
3730             streaming[OUTPUT_PORT] = true;
3731         }
3732     }
3733     if (m_debug.in_buffer_log) {
3734         venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
3735     }
3736 
3737     return true;
3738 }
3739 
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3740 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3741 {
3742     struct v4l2_buffer buf;
3743     struct v4l2_plane plane;
3744     int rc = 0;
3745     struct v4l2_control control;
3746     encoder_media_buffer_type * meta_buf = NULL;
3747     native_handle_t *hnd = NULL;
3748 
3749     if (bufhdr == NULL) {
3750         DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3751         return false;
3752     }
3753 
3754     bool status = true;
3755     if (metadatamode) {
3756         plane.m.userptr = (unsigned long)bufhdr->pBuffer;
3757         meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3758 
3759         if (!color_format) {
3760             if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3761                 hnd = (native_handle_t*)meta_buf->meta_handle;
3762                 if (!hnd) {
3763                     DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3764                     return false;
3765                 } else if (hnd->numFds > kMaxBuffersInBatch) {
3766                     DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3767                             "Max = %d", hnd->numFds, kMaxBuffersInBatch);
3768                     status = false;
3769                 }
3770                 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
3771             } else {
3772                 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3773                 status = false;
3774             }
3775         } else {
3776             DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3777             status = false;
3778         }
3779     } else {
3780         DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3781         status = false;
3782     }
3783 
3784     if (status) {
3785         OMX_TICKS bufTimeStamp = 0ll;
3786         int numBufs = hnd->numFds;
3787         int v4l2Ids[kMaxBuffersInBatch] = {-1};
3788         for (int i = 0; i < numBufs; ++i) {
3789             v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3790             if (v4l2Ids[i] < 0) {
3791                 DEBUG_PRINT_ERROR("Failed to register buffer");
3792                 // TODO: cleanup the map and purge all slots of current index
3793                 status = false;
3794                 break;
3795             }
3796         }
3797         for (int i = 0; i < numBufs; ++i) {
3798             int v4l2Id = v4l2Ids[i];
3799 
3800             memset(&buf, 0, sizeof(buf));
3801             memset(&plane, 0, sizeof(plane));
3802 
3803             DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3804             buf.index = (unsigned)v4l2Id;
3805             buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3806             buf.memory = V4L2_MEMORY_USERPTR;
3807             plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
3808             plane.reserved[1] = 0;
3809             plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
3810             plane.m.userptr = (unsigned long)meta_buf;
3811             plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
3812             buf.m.planes = &plane;
3813             buf.length = 1;
3814 
3815             if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3816                 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3817             if (i != numBufs - 1) {
3818                 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3819                 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
3820                         i, etb + 1, numBufs);
3821             }
3822 
3823 
3824             // timestamp differences from camera are in nano-seconds
3825             bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
3826 
3827             DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3828                 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
3829             buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3830             buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3831 
3832             rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3833             if (rc) {
3834                 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3835                 return false;
3836             }
3837 
3838             etb++;
3839         }
3840     }
3841 
3842     if (status && !streaming[OUTPUT_PORT]) {
3843         enum v4l2_buf_type buf_type;
3844         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3845         int ret;
3846         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3847         if (ret) {
3848             DEBUG_PRINT_ERROR("Failed to call streamon");
3849             if (errno == EBUSY) {
3850                 hw_overload = true;
3851             }
3852             status = false;
3853         } else {
3854             streaming[OUTPUT_PORT] = true;
3855         }
3856     }
3857 
3858     return status;
3859 }
3860 
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3861 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3862 {
3863     struct pmem *temp_buffer = NULL;
3864     struct venc_buffer  frameinfo;
3865     struct v4l2_buffer buf;
3866     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3867     int rc = 0;
3868     unsigned int extra_idx;
3869     struct OMX_BUFFERHEADERTYPE *bufhdr;
3870 
3871     if (buffer == NULL)
3872         return false;
3873 
3874     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3875 
3876     if (pmem_data_buf) {
3877         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3878         plane[0].m.userptr = (unsigned long)pmem_data_buf;
3879     } else {
3880         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3881         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3882     }
3883 
3884     memset(&buf, 0, sizeof(buf));
3885     memset(&plane, 0, sizeof(plane));
3886 
3887     buf.index = index;
3888     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3889     buf.memory = V4L2_MEMORY_USERPTR;
3890     plane[0].length = bufhdr->nAllocLen;
3891     plane[0].bytesused = bufhdr->nFilledLen;
3892     plane[0].reserved[0] = fd;
3893     plane[0].reserved[1] = 0;
3894     plane[0].data_offset = bufhdr->nOffset;
3895     buf.m.planes = plane;
3896     buf.length = num_output_planes;
3897     buf.flags = 0;
3898 
3899     if (mBatchSize) {
3900         // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
3901         // This results in the first batch being of size mBatchSize + 1, but thats good because
3902         // we need an extra FTB for the codec specific data.
3903 
3904         if (!ftb || ftb % mBatchSize) {
3905             buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3906             DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
3907         }
3908     }
3909 
3910     extra_idx = EXTRADATA_IDX(num_output_planes);
3911 
3912     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3913         char *userptr;
3914         int fd;
3915         unsigned offset;
3916         ssize_t size;
3917         int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
3918         if (rc != OMX_ErrorNone) {
3919             DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
3920             return false;
3921         }
3922         plane[extra_idx].bytesused = 0;
3923         plane[extra_idx].length = size;
3924         plane[extra_idx].m.userptr = (unsigned long)userptr;
3925 #ifdef USE_ION
3926         plane[extra_idx].reserved[0] = fd;
3927 #endif
3928         plane[extra_idx].reserved[1] = offset;
3929         plane[extra_idx].data_offset = 0;
3930     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3931         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3932         return false;
3933     }
3934 
3935     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3936 
3937     if (rc) {
3938         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3939         return false;
3940     }
3941 
3942     ftb++;
3943     return true;
3944 }
3945 
venc_set_inband_video_header(OMX_BOOL enable)3946 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
3947 {
3948     struct v4l2_control control;
3949 
3950     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
3951     if(enable) {
3952         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
3953     } else {
3954         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
3955     }
3956 
3957     DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
3958     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3959         DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
3960         return false;
3961     }
3962     return true;
3963 }
3964 
venc_set_au_delimiter(OMX_BOOL enable)3965 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
3966 {
3967     struct v4l2_control control;
3968 
3969     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
3970     if(enable) {
3971         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
3972     } else {
3973         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
3974     }
3975 
3976     DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
3977     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3978         DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
3979         return false;
3980     }
3981     return true;
3982 }
3983 
venc_set_mbi_statistics_mode(OMX_U32 mode)3984 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
3985 {
3986     struct v4l2_control control;
3987 
3988     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
3989     control.value = mode;
3990 
3991     DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
3992     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3993         DEBUG_PRINT_ERROR("Setting MBI mode failed");
3994         return false;
3995     }
3996     return true;
3997 }
3998 
venc_set_vqzip_sei_type(OMX_BOOL enable)3999 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
4000 {
4001     struct v4l2_control sei_control, yuvstats_control;
4002 
4003     DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
4004     sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
4005     yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4006 
4007     if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
4008         DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
4009     }
4010 
4011     if(enable) {
4012         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
4013         yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4014     } else {
4015         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
4016         yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4017     }
4018 
4019     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
4020         DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
4021     }
4022 
4023     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
4024         DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
4025     }
4026 #ifdef _VQZIP_
4027     vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
4028     vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
4029     vqzip.init();
4030     vqzip_sei_info.enabled = true;
4031 #endif
4032 
4033     return true;
4034 }
4035 
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)4036 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
4037 {
4038     // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
4039     if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
4040         return false;
4041 
4042     // Check for bframes with Hier-P-Hybrid
4043     if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
4044         return false;
4045 
4046     // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
4047     if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
4048            hier_layers.hier_mode == HIER_B || ltrinfo.count))
4049         return false;
4050 
4051     // Check for LTR with Hier-P-Hybrid
4052     if (count && hier_layers.hier_mode == HIER_P_HYBRID)
4053         return false;
4054 
4055     return true;
4056 }
4057 
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)4058 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
4059                                     OMX_U32 num_layers)
4060 {
4061     struct v4l2_control control;
4062 
4063     if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
4064         DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
4065         return false;
4066     }
4067 
4068     if (type == QOMX_HIERARCHICALCODING_P) {
4069         // Reduce layer count by 1 before sending to driver. This avoids
4070         // driver doing the same in multiple places.
4071         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
4072         control.value = num_layers - 1;
4073         DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
4074         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4075             DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
4076             return false;
4077         }
4078         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
4079         control.value = num_layers - 1;
4080         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
4081         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4082             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4083             return false;
4084         }
4085         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4086             DEBUG_PRINT_LOW("Set H264_SVC_NAL");
4087             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4088             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4089             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4090                 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4091                 return false;
4092             }
4093         }
4094         hier_layers.hier_mode = HIER_P;
4095     } else if (type == QOMX_HIERARCHICALCODING_B) {
4096         if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4097             DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
4098             return false;
4099         }
4100         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
4101         control.value = num_layers - 1;
4102         DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
4103         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4104             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4105             return false;
4106         }
4107         hier_layers.hier_mode = HIER_B;
4108     } else {
4109         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
4110         return false;
4111     }
4112     hier_layers.numlayers = num_layers;
4113     return true;
4114 }
4115 
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)4116 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
4117 {
4118     struct v4l2_control control;
4119 
4120     DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
4121 
4122     if (enable == OMX_FALSE) {
4123         /* No easy way to turn off extradata to the driver
4124          * at the moment */
4125         return false;
4126     }
4127 
4128     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4129     switch (extra_data) {
4130         case OMX_ExtraDataVideoEncoderSliceInfo:
4131             control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
4132             break;
4133         case OMX_ExtraDataVideoEncoderMBInfo:
4134             control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
4135             break;
4136         case OMX_ExtraDataFrameDimension:
4137             control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
4138             break;
4139         default:
4140             DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
4141             return false;
4142     }
4143 
4144     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4145         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
4146                 (unsigned int)extra_data, errno);
4147         return false;
4148     }
4149 
4150     return true;
4151 }
4152 
venc_set_slice_delivery_mode(OMX_U32 enable)4153 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
4154 {
4155     struct v4l2_control control;
4156 
4157     if (enable) {
4158         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
4159         control.value = 1;
4160         DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
4161 
4162         if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4163             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4164                 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
4165                 return false;
4166             } else {
4167                 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
4168                 slice_mode.enable = 1;
4169             }
4170         } else {
4171             DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
4172                     "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
4173                     m_sVenc_cfg.codectype);
4174         }
4175     } else {
4176         DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
4177     }
4178 
4179     return true;
4180 }
4181 
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)4182 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
4183 {
4184     int rc;
4185     struct v4l2_control control;
4186     struct v4l2_ext_control ctrl[4];
4187     struct v4l2_ext_controls controls;
4188 
4189     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
4190     ctrl[0].value = initqp->nQpI;
4191     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
4192     ctrl[1].value = initqp->nQpP;
4193     ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
4194     ctrl[2].value = initqp->nQpB;
4195     ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
4196     ctrl[3].value = initqp->bEnableInitQp;
4197 
4198     controls.count = 4;
4199     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4200     controls.controls = ctrl;
4201 
4202     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4203                     controls.controls[0].id, controls.controls[0].value,
4204                     controls.controls[1].id, controls.controls[1].value,
4205                     controls.controls[2].id, controls.controls[2].value,
4206                     controls.controls[3].id, controls.controls[3].value);
4207 
4208     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4209     if (rc) {
4210         DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
4211         return false;
4212     }
4213 
4214     init_qp.iframeqp = initqp->nQpI;
4215     init_qp.pframeqp = initqp->nQpP;
4216     init_qp.bframeqp = initqp->nQpB;
4217     init_qp.enableinitqp = initqp->bEnableInitQp;
4218 
4219     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4220                     controls.controls[0].id, controls.controls[0].value,
4221                     controls.controls[1].id, controls.controls[1].value,
4222                     controls.controls[2].id, controls.controls[2].value,
4223                     controls.controls[3].id, controls.controls[3].value);
4224     return true;
4225 }
4226 
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)4227 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
4228     OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
4229 {
4230     int rc;
4231     struct v4l2_control control;
4232 
4233     DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
4234         primaries, range, transfer_chars, matrix_coeffs);
4235 
4236     control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
4237     control.value = primaries;
4238 
4239     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4240     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4241 
4242     if (rc) {
4243         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
4244         return false;
4245     }
4246 
4247     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4248 
4249     color_space.primaries = control.value;
4250 
4251     control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
4252     control.value = range;
4253 
4254     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4255     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4256 
4257     if (rc) {
4258         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
4259         return false;
4260     }
4261 
4262     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4263 
4264     color_space.range = control.value;
4265 
4266     control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
4267     control.value = transfer_chars;
4268 
4269     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4270     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4271 
4272     if (rc) {
4273         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
4274         return false;
4275     }
4276 
4277     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4278 
4279     color_space.transfer_chars = control.value;
4280 
4281     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
4282     control.value = matrix_coeffs;
4283 
4284     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4285     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4286 
4287     if (rc) {
4288         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
4289         return false;
4290     }
4291 
4292     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4293 
4294     color_space.matrix_coeffs = control.value;
4295 
4296     return true;
4297 }
4298 
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)4299 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
4300 {
4301     int rc;
4302     struct v4l2_control control;
4303 
4304     control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
4305     control.value = i_frame_qp;
4306 
4307     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4308     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4309 
4310     if (rc) {
4311         DEBUG_PRINT_ERROR("Failed to set control");
4312         return false;
4313     }
4314 
4315     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4316     session_qp.iframeqp = control.value;
4317 
4318     control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
4319     control.value = p_frame_qp;
4320 
4321     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4322     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4323 
4324     if (rc) {
4325         DEBUG_PRINT_ERROR("Failed to set control");
4326         return false;
4327     }
4328 
4329     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4330 
4331     session_qp.pframeqp = control.value;
4332 
4333     if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
4334             (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4335 
4336         control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
4337         control.value = b_frame_qp;
4338 
4339         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4340         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4341 
4342         if (rc) {
4343             DEBUG_PRINT_ERROR("Failed to set control");
4344             return false;
4345         }
4346 
4347         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4348 
4349         session_qp.bframeqp = control.value;
4350     }
4351 
4352     return true;
4353 }
4354 
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)4355 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
4356 {
4357     int rc;
4358     struct v4l2_control control;
4359 
4360     if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
4361 
4362         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4363             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
4364         else
4365             control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
4366         control.value = min_qp;
4367 
4368         DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
4369                 control.id, control.value);
4370         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4371         if (rc) {
4372             DEBUG_PRINT_ERROR("Failed to set control");
4373             return false;
4374         }
4375 
4376         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4377             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
4378         else
4379             control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
4380         control.value = max_qp;
4381 
4382         DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
4383                 control.id, control.value);
4384         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4385         if (rc) {
4386             DEBUG_PRINT_ERROR("Failed to set control");
4387             return false;
4388         }
4389     } else {
4390         DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
4391             (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
4392     }
4393 
4394     return true;
4395 }
4396 
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)4397 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
4398 {
4399     struct venc_profile requested_profile = {0};
4400     struct ven_profilelevel requested_level = {0};
4401     unsigned long mb_per_frame = 0;
4402     DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
4403             (unsigned int)eProfile, (unsigned int)eLevel);
4404     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4405         ((m_sVenc_cfg.dvs_width + 15) >> 4);
4406 
4407     if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
4408         DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
4409         return true;
4410     }
4411 
4412     if (vqzip_sei_info.enabled) {
4413         DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
4414         return true;
4415     }
4416 
4417     DEBUG_PRINT_LOW("Validating Profile/Level from table");
4418 
4419     if (!venc_validate_profile_level(&eProfile, &eLevel)) {
4420         DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
4421         return false;
4422     }
4423 
4424     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4425         DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
4426                 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
4427                 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
4428 
4429         if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4430             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
4431         } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4432             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
4433         } else {
4434             DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
4435                     (unsigned int)eProfile);
4436             return false;
4437         }
4438 
4439         DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
4440                 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
4441                 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
4442                 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
4443 
4444         if (mb_per_frame >= 3600) {
4445             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4446                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4447 
4448             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4449                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4450         } else {
4451             switch (eLevel) {
4452                 case OMX_VIDEO_MPEG4Level0:
4453                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
4454                     break;
4455                 case OMX_VIDEO_MPEG4Level0b:
4456                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
4457                     break;
4458                 case OMX_VIDEO_MPEG4Level1:
4459                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
4460                     break;
4461                 case OMX_VIDEO_MPEG4Level2:
4462                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
4463                     break;
4464                 case OMX_VIDEO_MPEG4Level3:
4465                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
4466                     break;
4467                 case OMX_VIDEO_MPEG4Level4a:
4468                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
4469                     break;
4470                 case OMX_VIDEO_MPEG4Level5:
4471                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4472                     break;
4473                 default:
4474                     return false;
4475                     // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
4476                     break;
4477             }
4478         }
4479     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4480 
4481         switch (eProfile) {
4482             case OMX_VIDEO_H263ProfileBaseline:
4483                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
4484                 break;
4485             case OMX_VIDEO_H263ProfileH320Coding:
4486                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
4487                 break;
4488             case OMX_VIDEO_H263ProfileBackwardCompatible:
4489                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
4490                 break;
4491             case OMX_VIDEO_H263ProfileISWV2:
4492                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
4493                 break;
4494             case OMX_VIDEO_H263ProfileISWV3:
4495                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
4496                 break;
4497             case OMX_VIDEO_H263ProfileHighCompression:
4498                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
4499                 break;
4500             case OMX_VIDEO_H263ProfileInternet:
4501                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
4502                 break;
4503             case OMX_VIDEO_H263ProfileInterlace:
4504                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
4505                 break;
4506             case OMX_VIDEO_H263ProfileHighLatency:
4507                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
4508                 break;
4509             default:
4510                 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
4511                         requested_profile.profile);
4512                 return false;
4513         }
4514 
4515         //profile level
4516         switch (eLevel) {
4517             case OMX_VIDEO_H263Level10:
4518                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
4519                 break;
4520             case OMX_VIDEO_H263Level20:
4521                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
4522                 break;
4523             case OMX_VIDEO_H263Level30:
4524                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
4525                 break;
4526             case OMX_VIDEO_H263Level40:
4527                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
4528                 break;
4529             case OMX_VIDEO_H263Level45:
4530                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
4531                 break;
4532             case OMX_VIDEO_H263Level50:
4533                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
4534                 break;
4535             case OMX_VIDEO_H263Level60:
4536                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
4537                 break;
4538             case OMX_VIDEO_H263Level70:
4539                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
4540                 break;
4541             default:
4542                 return false;
4543                 break;
4544         }
4545     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4546         if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
4547             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
4548         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
4549             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
4550         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh) {
4551             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
4552         } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
4553             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
4554         } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
4555             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
4556         } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
4557             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
4558         } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
4559             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
4560         } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
4561             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
4562         } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
4563             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
4564         } else {
4565             DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
4566                     requested_profile.profile);
4567             return false;
4568         }
4569 
4570         //profile level
4571         switch (eLevel) {
4572             case OMX_VIDEO_AVCLevel1:
4573                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
4574                 break;
4575             case OMX_VIDEO_AVCLevel1b:
4576                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
4577                 break;
4578             case OMX_VIDEO_AVCLevel11:
4579                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
4580                 break;
4581             case OMX_VIDEO_AVCLevel12:
4582                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
4583                 break;
4584             case OMX_VIDEO_AVCLevel13:
4585                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
4586                 break;
4587             case OMX_VIDEO_AVCLevel2:
4588                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
4589                 break;
4590             case OMX_VIDEO_AVCLevel21:
4591                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
4592                 break;
4593             case OMX_VIDEO_AVCLevel22:
4594                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
4595                 break;
4596             case OMX_VIDEO_AVCLevel3:
4597                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
4598                 break;
4599             case OMX_VIDEO_AVCLevel31:
4600                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
4601                 break;
4602             case OMX_VIDEO_AVCLevel32:
4603                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
4604                 break;
4605             case OMX_VIDEO_AVCLevel4:
4606                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
4607                 break;
4608             case OMX_VIDEO_AVCLevel41:
4609                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
4610                 break;
4611             case OMX_VIDEO_AVCLevel42:
4612                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
4613                 break;
4614             case OMX_VIDEO_AVCLevel5:
4615                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
4616                 break;
4617             case OMX_VIDEO_AVCLevel51:
4618                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
4619                 break;
4620             case OMX_VIDEO_AVCLevel52:
4621                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4622                 break;
4623             case OMX_VIDEO_AVCLevelMax:
4624                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4625                 break;
4626             default :
4627                 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
4628                         requested_level.level);
4629                 return false;
4630                 break;
4631         }
4632     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4633         if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
4634             DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
4635                         (unsigned int)eProfile);
4636             return false;
4637         }
4638         requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
4639         m_profile_set = true;
4640         switch(eLevel) {
4641             case OMX_VIDEO_VP8Level_Version0:
4642                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
4643                 break;
4644             case OMX_VIDEO_VP8Level_Version1:
4645                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
4646                 break;
4647             default:
4648                 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
4649                             (unsigned int)eLevel);
4650                 return false;
4651                 break;
4652         }
4653     }  else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4654         if (eProfile == OMX_VIDEO_HEVCProfileMain) {
4655             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
4656         } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
4657             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
4658         } else {
4659             DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
4660                     requested_profile.profile);
4661             return false;
4662         }
4663 
4664         //profile level
4665         switch (eLevel) {
4666             case OMX_VIDEO_HEVCMainTierLevel1:
4667                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
4668                 break;
4669             case OMX_VIDEO_HEVCHighTierLevel1:
4670                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
4671                 break;
4672             case OMX_VIDEO_HEVCMainTierLevel2:
4673                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
4674                 break;
4675             case OMX_VIDEO_HEVCHighTierLevel2:
4676                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
4677                 break;
4678             case OMX_VIDEO_HEVCMainTierLevel21:
4679                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
4680                 break;
4681             case OMX_VIDEO_HEVCHighTierLevel21:
4682                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
4683                 break;
4684             case OMX_VIDEO_HEVCMainTierLevel3:
4685                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
4686                 break;
4687             case OMX_VIDEO_HEVCHighTierLevel3:
4688                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
4689                 break;
4690             case OMX_VIDEO_HEVCMainTierLevel31:
4691                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
4692                 break;
4693             case OMX_VIDEO_HEVCHighTierLevel31:
4694                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
4695                 break;
4696             case OMX_VIDEO_HEVCMainTierLevel4:
4697                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
4698                 break;
4699             case OMX_VIDEO_HEVCHighTierLevel4:
4700                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
4701                 break;
4702             case OMX_VIDEO_HEVCMainTierLevel41:
4703                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
4704                 break;
4705             case OMX_VIDEO_HEVCHighTierLevel41:
4706                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
4707                 break;
4708             case OMX_VIDEO_HEVCMainTierLevel5:
4709                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
4710                 break;
4711             case OMX_VIDEO_HEVCHighTierLevel5:
4712                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
4713                 break;
4714             case OMX_VIDEO_HEVCMainTierLevel51:
4715                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
4716                 break;
4717             case OMX_VIDEO_HEVCHighTierLevel51:
4718                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
4719                 break;
4720             case OMX_VIDEO_HEVCMainTierLevel52:
4721                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
4722                 break;
4723             case OMX_VIDEO_HEVCHighTierLevel52:
4724                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
4725                 break;
4726             case OMX_VIDEO_HEVCMainTierLevel6:
4727                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
4728                 break;
4729             case OMX_VIDEO_HEVCHighTierLevel6:
4730                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
4731                 break;
4732             case OMX_VIDEO_HEVCMainTierLevel61:
4733                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
4734                 break;
4735             case OMX_VIDEO_HEVCHighTierLevel61:
4736                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
4737                 break;
4738             default :
4739                 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
4740                         requested_level.level);
4741                 return false;
4742         }
4743     }
4744 
4745     if (!m_profile_set) {
4746         int rc;
4747         struct v4l2_control control;
4748 
4749         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4750             control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
4751         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4752             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
4753         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4754             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
4755         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4756             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
4757         } else {
4758             DEBUG_PRINT_ERROR("Wrong CODEC");
4759             return false;
4760         }
4761 
4762         control.value = requested_profile.profile;
4763 
4764         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4765         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4766 
4767         if (rc) {
4768             DEBUG_PRINT_ERROR("Failed to set control");
4769             return false;
4770         }
4771 
4772         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4773 
4774         codec_profile.profile = control.value;
4775         m_profile_set = true;
4776     }
4777 
4778     if (!m_level_set) {
4779         int rc;
4780         struct v4l2_control control;
4781 
4782         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4783             control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
4784         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4785             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
4786         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4787             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
4788         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4789             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
4790         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4791             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
4792         } else {
4793             DEBUG_PRINT_ERROR("Wrong CODEC");
4794             return false;
4795         }
4796 
4797         control.value = requested_level.level;
4798 
4799         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4800         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4801 
4802         if (rc) {
4803             DEBUG_PRINT_ERROR("Failed to set control");
4804             return false;
4805         }
4806 
4807         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4808 
4809         profile_level.level = control.value;
4810         m_level_set = true;
4811     }
4812 
4813     return true;
4814 }
4815 
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)4816 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
4817 {
4818 
4819     struct venc_voptimingcfg vop_timing_cfg;
4820 
4821     DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
4822             (unsigned int)TimeIncRes);
4823 
4824     vop_timing_cfg.voptime_resolution = TimeIncRes;
4825 
4826     voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
4827     return true;
4828 }
4829 
venc_set_intra_period_config(OMX_U32 nPFrames,OMX_U32 nBFrames)4830 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
4831 #if _ANDROID_
4832     // Android defines nBFrames as number of Bs between I OR P
4833     // Per the spec, nBFrames is number of Bs between I
4834     OMX_U32 nBs = nBFrames * (nPFrames + 1);
4835     DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
4836     nBFrames = nBs;
4837 #endif //_ANDROID_
4838    return venc_set_intra_period(nPFrames, nBFrames);
4839 }
4840 
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)4841 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
4842 {
4843 
4844     DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
4845     int rc;
4846     struct v4l2_control control;
4847     int pframe = 0, bframe = 0;
4848 
4849     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
4850             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
4851             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
4852             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
4853             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4854         nBFrames=0;
4855     }
4856 
4857     if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
4858         DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
4859         return false;
4860     }
4861 
4862     intra_period.num_pframes = nPFrames;
4863     intra_period.num_bframes = nBFrames;
4864 
4865     if (!venc_calibrate_gop() && !is_thulium_v1)
4866     {
4867         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4868         return false;
4869     }
4870 
4871     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4872     control.value = intra_period.num_pframes;
4873     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4874 
4875     if (rc) {
4876         DEBUG_PRINT_ERROR("Failed to set control");
4877         return false;
4878     }
4879 
4880     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4881 
4882     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4883     control.value = intra_period.num_bframes;
4884     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4885     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4886 
4887     if (rc) {
4888         DEBUG_PRINT_ERROR("Failed to set control");
4889         return false;
4890     }
4891 
4892     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
4893 
4894     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
4895         m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4896         control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4897         control.value = 1;
4898 
4899         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4900 
4901         if (rc) {
4902             DEBUG_PRINT_ERROR("Failed to set control");
4903             return false;
4904         }
4905         idrperiod.idrperiod = 1;
4906     }
4907     return true;
4908 }
4909 
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)4910 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
4911 {
4912     int rc = 0;
4913     struct v4l2_control control;
4914     DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
4915             (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
4916 
4917     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
4918         DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
4919         return false;
4920     }
4921 
4922     if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
4923         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4924         return false;
4925     }
4926 
4927     if (!intra_period.num_bframes)
4928         intra_period.num_pframes = nPFrames;
4929     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4930     control.value = nIDRPeriod;
4931 
4932     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4933 
4934     if (rc) {
4935         DEBUG_PRINT_ERROR("Failed to set control");
4936         return false;
4937     }
4938 
4939     idrperiod.idrperiod = nIDRPeriod;
4940     return true;
4941 }
4942 
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)4943 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
4944 {
4945     int rc = 0;
4946     struct v4l2_control control;
4947 
4948     DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
4949 
4950     if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
4951             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
4952 
4953         control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
4954         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4955 
4956         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4957         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4958 
4959         if (rc) {
4960             DEBUG_PRINT_ERROR("Failed to set control");
4961             return false;
4962         }
4963 
4964         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4965         entropy.longentropysel = control.value;
4966 
4967         if (i_cabac_level == 0) {
4968             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
4969         } else if (i_cabac_level == 1) {
4970             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
4971         } else if (i_cabac_level == 2) {
4972             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
4973         }
4974 
4975         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
4976         //control.value = entropy_cfg.cabacmodel;
4977         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4978         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4979 
4980         if (rc) {
4981             DEBUG_PRINT_ERROR("Failed to set control");
4982             return false;
4983         }
4984 
4985         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4986         entropy.cabacmodel=control.value;
4987     } else if (!enable) {
4988         control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
4989         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4990         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4991         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4992 
4993         if (rc) {
4994             DEBUG_PRINT_ERROR("Failed to set control");
4995             return false;
4996         }
4997 
4998         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4999         entropy.longentropysel=control.value;
5000     } else {
5001         DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
5002         return false;
5003     }
5004 
5005     return true;
5006 }
5007 
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)5008 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
5009 {
5010     int rc;
5011     struct v4l2_control control;
5012     bool status = true;
5013 
5014     if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
5015         control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
5016     } else {
5017         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5018     }
5019 
5020     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5021     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5022     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5023 
5024     if (rc) {
5025         DEBUG_PRINT_ERROR("Failed to set control");
5026         return false;
5027     }
5028 
5029     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5030     multislice.mslice_mode=control.value;
5031 
5032     if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
5033 
5034         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
5035         control.value = nSlicesize;
5036         DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
5037         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5038 
5039         if (rc) {
5040             DEBUG_PRINT_ERROR("Failed to set control");
5041             return false;
5042         }
5043 
5044         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5045         multislice.mslice_size=control.value;
5046 
5047     }
5048 
5049     return status;
5050 }
5051 
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)5052 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
5053 {
5054     bool status = true;
5055     int rc;
5056     struct v4l2_control control_mode,control_mbs;
5057     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
5058 
5059     // There is no disabled mode.  Disabled mode is indicated by a 0 count.
5060     if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
5061         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
5062         return status;
5063     } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
5064             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5065         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
5066         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
5067         control_mbs.value=irMBs;
5068     } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
5069             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5070         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
5071         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5072         control_mbs.value=irMBs;
5073     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
5074             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5075         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
5076     } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
5077             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5078         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
5079         control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5080         control_mbs.value = irMBs;
5081     } else {
5082         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
5083                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
5084         return false;
5085     }
5086 
5087     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
5088     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
5089 
5090     if (rc) {
5091         DEBUG_PRINT_ERROR("Failed to set control");
5092         return false;
5093     }
5094 
5095     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
5096 
5097     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
5098     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
5099 
5100     if (rc) {
5101         DEBUG_PRINT_ERROR("Failed to set control");
5102         return false;
5103     }
5104 
5105     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
5106 
5107     intra_refresh.irmode = control_mode.value;
5108     intra_refresh.mbcount = control_mbs.value;
5109 
5110     return status;
5111 }
5112 
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)5113 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
5114 {
5115     bool status = true;
5116     struct venc_headerextension hec_cfg;
5117     struct venc_multiclicecfg multislice_cfg;
5118     int rc;
5119     OMX_U32 resynchMarkerSpacingBytes = 0;
5120     struct v4l2_control control;
5121 
5122     memset(&control, 0, sizeof(control));
5123 
5124     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5125         if (error_resilience->bEnableHEC) {
5126             hec_cfg.header_extension = 1;
5127         } else {
5128             hec_cfg.header_extension = 0;
5129         }
5130 
5131         hec.header_extension = error_resilience->bEnableHEC;
5132     }
5133 
5134     if (error_resilience->bEnableRVLC) {
5135         DEBUG_PRINT_ERROR("RVLC is not Supported");
5136         return false;
5137     }
5138 
5139     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5140             (error_resilience->bEnableDataPartitioning)) {
5141         DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
5142         return false;
5143     }
5144 
5145     if (error_resilience->nResynchMarkerSpacing) {
5146         resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
5147         resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
5148     }
5149     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5150             (error_resilience->nResynchMarkerSpacing)) {
5151         multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
5152         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5153         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5154         control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
5155     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
5156             error_resilience->bEnableDataPartitioning) {
5157         multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
5158         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5159         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5160         control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
5161     } else {
5162         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
5163         multislice_cfg.mslice_size = 0;
5164         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5165         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5166     }
5167 
5168     DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
5169             multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
5170     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5171     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5172 
5173     if (rc) {
5174        DEBUG_PRINT_ERROR("Failed to set Slice mode control");
5175         return false;
5176     }
5177 
5178     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5179     multislice.mslice_mode=control.value;
5180 
5181     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
5182     control.value = resynchMarkerSpacingBytes;
5183     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5184 
5185     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5186 
5187     if (rc) {
5188        DEBUG_PRINT_ERROR("Failed to set MAX MB control");
5189         return false;
5190     }
5191 
5192     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5193     multislice.mslice_mode = multislice_cfg.mslice_mode;
5194     multislice.mslice_size = multislice_cfg.mslice_size;
5195     return status;
5196 }
5197 
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)5198 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
5199 {
5200     int rc;
5201     struct v4l2_control control;
5202     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
5203 
5204     if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
5205         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
5206     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
5207         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
5208     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
5209         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
5210     }
5211 
5212     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5213     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5214 
5215     if (rc) {
5216         return false;
5217     }
5218 
5219     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5220 
5221     dbkfilter.db_mode=control.value;
5222 
5223     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
5224     control.value=0;
5225 
5226     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5227     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5228 
5229     if (rc) {
5230         return false;
5231     }
5232 
5233     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5234     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
5235     control.value=0;
5236     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5237     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5238 
5239     if (rc) {
5240         return false;
5241     }
5242 
5243     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5244 
5245 
5246     dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
5247     return true;
5248 }
5249 
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)5250 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
5251 {
5252     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
5253             (unsigned int)nTargetBitrate);
5254     struct v4l2_control control;
5255     int rc = 0;
5256     control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
5257     control.value = nTargetBitrate;
5258 
5259     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5260     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5261 
5262     if (rc) {
5263         DEBUG_PRINT_ERROR("Failed to set control");
5264         return false;
5265     }
5266 
5267     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5268 
5269 
5270     m_sVenc_cfg.targetbitrate = control.value;
5271     bitrate.target_bitrate = control.value;
5272 
5273     if (!config) {
5274         m_level_set = false;
5275 
5276         if (venc_set_profile_level(0, 0)) {
5277             DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
5278         }
5279     }
5280 
5281     // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
5282     //  has been specified
5283     if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
5284         OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
5285                 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5286 
5287         DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
5288         for (OMX_U32 i = 0; i < numLayers; ++i) {
5289             layerBitrates[i] =
5290                     (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
5291             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
5292                     i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
5293                     layerBitrates[i], bitrate.target_bitrate);
5294         }
5295         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
5296             return false;
5297         }
5298     }
5299 
5300     return true;
5301 }
5302 
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)5303 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
5304 {
5305     struct v4l2_streamparm parm;
5306     int rc = 0;
5307     struct venc_framerate frame_rate_cfg;
5308     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
5309     parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5310     parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
5311     parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
5312 
5313     if (frame_rate_cfg.fps_numerator > 0)
5314         rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
5315 
5316     if (rc) {
5317         DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
5318         return false;
5319     }
5320 
5321     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
5322     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
5323 
5324     if (!config) {
5325         m_level_set = false;
5326 
5327         if (venc_set_profile_level(0, 0)) {
5328             DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
5329         }
5330     }
5331 
5332     return true;
5333 }
5334 
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)5335 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
5336 {
5337     struct v4l2_format fmt;
5338     int color_space = 0;
5339     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
5340 
5341     switch ((int)color_format) {
5342         case OMX_COLOR_FormatYUV420SemiPlanar:
5343         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
5344             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
5345             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5346             break;
5347         case QOMX_COLOR_FormatYVU420SemiPlanar:
5348             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
5349             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5350             break;
5351         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
5352             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
5353             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5354             break;
5355         case QOMX_COLOR_Format32bitRGBA8888:
5356             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
5357             break;
5358         case QOMX_COLOR_Format32bitRGBA8888Compressed:
5359             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
5360             break;
5361         default:
5362             DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
5363             m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
5364             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5365             DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
5366             break;
5367     }
5368 
5369     memset(&fmt, 0, sizeof(fmt));
5370     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5371     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
5372     fmt.fmt.pix_mp.colorspace = color_space;
5373     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
5374     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
5375 
5376     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5377         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
5378         return false;
5379     }
5380 
5381     return true;
5382 }
5383 
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)5384 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
5385 {
5386     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
5387 
5388     if (intra_vop_refresh == OMX_TRUE) {
5389         struct v4l2_control control;
5390         int rc;
5391         control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
5392         control.value = 1;
5393        DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5394         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5395 
5396         if (rc) {
5397            DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
5398             return false;
5399         }
5400 
5401        DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5402     } else {
5403         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
5404     }
5405 
5406     return true;
5407 }
5408 
venc_set_deinterlace(OMX_U32 enable)5409 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
5410 {
5411     DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
5412     struct v4l2_control control;
5413     int rc;
5414     control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
5415     if (enable)
5416         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5417     else
5418         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5419 
5420     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5421     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5422     if (rc) {
5423         DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
5424         return false;
5425     }
5426     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5427     deinterlace_enabled = true;
5428     return true;
5429 }
5430 
venc_calibrate_gop()5431 bool venc_dev::venc_calibrate_gop()
5432 {
5433     int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
5434     int num_sub_gops_in_a_gop;
5435     nPframes = intra_period.num_pframes;
5436     nBframes = intra_period.num_bframes;
5437     nLayers = hier_layers.numlayers;
5438     if (temporal_layers_config.nPLayers) {
5439         nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5440     }
5441 
5442     if (!nPframes && nLayers) {
5443         DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
5444         return false;
5445     }
5446 
5447     if (nLayers > 1) { /*Multi-layer encoding*/
5448         sub_gop_size = 1 << (nLayers - 1);
5449         /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
5450          * below calculations we are ignoring +1 . Ignoring +1 in below
5451          * calculations is not a mistake but intentional.
5452          */
5453         gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
5454         num_sub_gops_in_a_gop = gop_size/sub_gop_size;
5455         if (nBframes) { /*Hier-B case*/
5456         /*
5457             * Frame Type--> I  B  B  B  P  B  B  B  P  I  B  B  P ...
5458             * Layer -->     0  2  1  2  0  2  1  2  0  0  2  1  2 ...
5459             * nPframes = 2, nBframes = 6, nLayers = 3
5460             *
5461             * Intention is to keep the intraperiod as close as possible to what is desired
5462             * by the client while adjusting nPframes and nBframes to meet other constraints.
5463             * eg1: Input by client: nPframes =  9, nBframes = 14, nLayers = 2
5464             *    Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
5465             *
5466             * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
5467             *    Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
5468             */
5469             nPframes = num_sub_gops_in_a_gop;
5470             nBframes = gop_size - nPframes;
5471         } else { /*Hier-P case*/
5472             /*
5473             * Frame Type--> I  P  P  P  P  P  P  P  I  P  P  P  P ...
5474             * Layer-->      0  2  1  2  0  2  1  2  0  2  1  2  0 ...
5475             * nPframes =  7, nBframes = 0, nLayers = 3
5476             *
5477             * Intention is to keep the intraperiod as close as possible to what is desired
5478             * by the client while adjusting nPframes and nBframes to meet other constraints.
5479             * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
5480             *    Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
5481             *
5482             * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
5483             *     Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
5484             */
5485             nPframes = gop_size - 1;
5486         }
5487     } else { /*Single-layer encoding*/
5488         if (nBframes) {
5489             /* I  P  B  B  B  P  B  B  B   P   B   B   B   I   P   B   B...
5490             *  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17...
5491             * nPframes = 3, nBframes = 9, nLayers = 0
5492             *
5493             * ratio is rounded,
5494             * eg1: nPframes = 9, nBframes = 11 => ratio = 1
5495             * eg2: nPframes = 9, nBframes = 16 => ratio = 2
5496             */
5497             ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
5498             nBframes = ratio * nPframes;
5499         }
5500     }
5501     DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
5502         intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
5503     intra_period.num_pframes = nPframes;
5504     intra_period.num_bframes = nBframes;
5505     hier_layers.numlayers = nLayers;
5506     return true;
5507 }
5508 
venc_set_bitrate_type(OMX_U32 type)5509 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
5510 {
5511     struct v4l2_control control;
5512     int rc = 0;
5513     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
5514     control.value = type;
5515     DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
5516     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5517     if (rc) {
5518         DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
5519             bitrate_type_string(type));
5520         return false;
5521     }
5522     return true;
5523 }
5524 
venc_set_layer_bitrates(OMX_U32 * layerBitrate,OMX_U32 numLayers)5525 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
5526 {
5527     DEBUG_PRINT_LOW("venc_set_layer_bitrates");
5528     struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
5529     struct v4l2_ext_controls controls;
5530     int rc = 0;
5531     OMX_U32 i;
5532 
5533     if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
5534         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
5535         return false;
5536     }
5537 
5538     for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
5539         if (!layerBitrate[i]) {
5540             DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
5541             return false;
5542         } else {
5543             ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
5544             ctrl[i].value = layerBitrate[i];
5545         }
5546     }
5547     controls.count = numLayers;
5548     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5549     controls.controls = ctrl;
5550 
5551     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5552     if (rc) {
5553         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
5554         return false;
5555     }
5556 
5557     DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
5558     return true;
5559 }
5560 
venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE * hhp)5561 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
5562 {
5563     DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
5564     struct v4l2_control control;
5565     int rc;
5566 
5567     if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
5568         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5569         return false;
5570     }
5571 
5572     if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
5573         DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
5574         return false;
5575     }
5576     if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
5577        DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
5578        return false;
5579     }
5580 
5581     hier_layers.numlayers = hhp->nHpLayers;
5582     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5583         hier_layers.hier_mode = HIER_P_HYBRID;
5584     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5585         hier_layers.hier_mode = HIER_P;
5586     }
5587     if (venc_calibrate_gop()) {
5588      // Update the driver with the new nPframes and nBframes
5589         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
5590         control.value = intra_period.num_pframes;
5591         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5592         if (rc) {
5593             DEBUG_PRINT_ERROR("Failed to set control");
5594             return false;
5595         }
5596 
5597         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
5598         control.value = intra_period.num_bframes;
5599         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5600         if (rc) {
5601             DEBUG_PRINT_ERROR("Failed to set control");
5602             return false;
5603         }
5604         DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
5605                          intra_period.num_pframes, intra_period.num_bframes);
5606     } else {
5607         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5608         return false;
5609     }
5610     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5611         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
5612     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5613         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
5614     }
5615     control.value = hhp->nHpLayers - 1;
5616 
5617     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
5618                     control.id, control.value);
5619 
5620     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5621     if (rc) {
5622         DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
5623         return false;
5624     }
5625 
5626     DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
5627                     control.id, control.value);
5628     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5629         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
5630         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
5631         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5632             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5633             return false;
5634         }
5635     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5636         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
5637         control.value = hhp->nHpLayers - 1;
5638         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5639             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5640             return false;
5641         }
5642     } else {
5643         DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
5644         return false;
5645     }
5646 
5647     if(venc_set_session_qp_range (hhp->nMinQuantizer,
5648                 hhp->nMaxQuantizer) == false) {
5649         DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
5650             (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
5651         return false;
5652     } else {
5653         session_qp_values.minqp = hhp->nMinQuantizer;
5654         session_qp_values.maxqp = hhp->nMaxQuantizer;
5655     }
5656 
5657     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
5658     for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
5659         layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
5660         hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
5661         DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
5662     }
5663     if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
5664        DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
5665             hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
5666             hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
5667             hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
5668        return false;
5669     }
5670     hybrid_hp.nHpLayers = hhp->nHpLayers;
5671 
5672     // Set this or else the layer0 bitrate will be overwritten by
5673     // default value in component
5674     m_sVenc_cfg.targetbitrate  = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
5675     hybrid_hp.nHpLayers = hhp->nHpLayers;
5676     hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
5677     hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
5678     hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
5679     return true;
5680 }
5681 
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)5682 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
5683 {
5684     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
5685     struct v4l2_ext_control ctrl[2];
5686     struct v4l2_ext_controls controls;
5687     int rc;
5688 
5689     if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
5690         DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
5691         return false;
5692     }
5693 
5694     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
5695     if (enable)
5696         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
5697     else
5698         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
5699 
5700     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
5701     if (enable && count > 0)
5702         ctrl[1].value = count;
5703     else if (enable)
5704         ctrl[1].value = 1;
5705     else
5706         ctrl[1].value = 0;
5707 
5708     controls.count = 2;
5709     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5710     controls.controls = ctrl;
5711 
5712     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
5713                     controls.controls[0].id, controls.controls[0].value,
5714                     controls.controls[1].id, controls.controls[1].value);
5715 
5716     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5717     if (rc) {
5718         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5719         return false;
5720     }
5721     ltrinfo.enabled = enable;
5722     ltrinfo.count = count;
5723 
5724     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
5725                     controls.controls[0].id, controls.controls[0].value,
5726                     controls.controls[1].id, controls.controls[1].value);
5727 
5728     if (!venc_set_profile_level(0, 0)) {
5729         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
5730                 __func__);
5731     } else {
5732         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
5733                 __func__, codec_profile.profile, profile_level.level);
5734     }
5735 
5736     return true;
5737 }
5738 
venc_set_useltr(OMX_U32 frameIdx)5739 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
5740 {
5741     DEBUG_PRINT_LOW("venc_use_goldenframe");
5742     int rc = true;
5743     struct v4l2_control control;
5744 
5745     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
5746     control.value = frameIdx;
5747 
5748     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5749     if (rc) {
5750         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
5751         return false;
5752     }
5753 
5754     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5755                     control.id, control.value);
5756     return true;
5757 }
5758 
venc_set_markltr(OMX_U32 frameIdx)5759 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
5760 {
5761     DEBUG_PRINT_LOW("venc_set_goldenframe");
5762     int rc = true;
5763     struct v4l2_control control;
5764 
5765     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
5766     control.value = frameIdx;
5767 
5768     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5769     if (rc) {
5770         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5771         return false;
5772     }
5773 
5774     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5775                     control.id, control.value);
5776     return true;
5777 }
5778 
venc_set_vpe_rotation(OMX_S32 rotation_angle)5779 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
5780 {
5781     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
5782     struct v4l2_control control;
5783     int rc;
5784     struct v4l2_format fmt;
5785     struct v4l2_requestbuffers bufreq;
5786 
5787     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
5788     if (rotation_angle == 0)
5789         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
5790     else if (rotation_angle == 90)
5791         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
5792     else if (rotation_angle == 180)
5793         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
5794     else if (rotation_angle == 270)
5795         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
5796     else {
5797         DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
5798         return false;
5799     }
5800 
5801     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5802     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5803     if (rc) {
5804         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
5805         return false;
5806     }
5807     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5808 
5809     memset(&fmt, 0, sizeof(fmt));
5810     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5811     if (rotation_angle == 90 || rotation_angle == 270) {
5812         OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
5813         OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
5814         m_sVenc_cfg.dvs_height = nHeight;
5815         m_sVenc_cfg.dvs_width = nWidth;
5816         DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
5817                 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
5818     }
5819 
5820     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
5821     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
5822     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
5823     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5824         DEBUG_PRINT_ERROR("Failed to set format on capture port");
5825         return false;
5826     }
5827 
5828     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
5829     bufreq.memory = V4L2_MEMORY_USERPTR;
5830     bufreq.count = m_sOutput_buff_property.actualcount;
5831     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5832     if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
5833         DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
5834             return false;
5835     }
5836     if (bufreq.count >= m_sOutput_buff_property.mincount)
5837         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
5838 
5839     return true;
5840 }
5841 
venc_set_searchrange()5842 bool venc_dev::venc_set_searchrange()
5843 {
5844     DEBUG_PRINT_LOW("venc_set_searchrange");
5845     struct v4l2_control control;
5846     struct v4l2_ext_control ctrl[6];
5847     struct v4l2_ext_controls controls;
5848     int rc;
5849 
5850     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5851         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5852         ctrl[0].value = 16;
5853         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5854         ctrl[1].value = 4;
5855         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5856         ctrl[2].value = 16;
5857         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5858         ctrl[3].value = 4;
5859         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5860         ctrl[4].value = 12;
5861         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5862         ctrl[5].value = 4;
5863     } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
5864                (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
5865         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5866         ctrl[0].value = 16;
5867         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5868         ctrl[1].value = 4;
5869         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5870         ctrl[2].value = 16;
5871         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5872         ctrl[3].value = 4;
5873         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5874         ctrl[4].value = 12;
5875         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5876         ctrl[5].value = 4;
5877     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5878         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5879         ctrl[0].value = 4;
5880         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5881         ctrl[1].value = 4;
5882         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5883         ctrl[2].value = 4;
5884         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5885         ctrl[3].value = 4;
5886         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5887         ctrl[4].value = 4;
5888         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5889         ctrl[5].value = 4;
5890     } else {
5891         DEBUG_PRINT_ERROR("Invalid codec type");
5892         return false;
5893     }
5894     controls.count = 6;
5895     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5896     controls.controls = ctrl;
5897 
5898     DEBUG_PRINT_LOW(" Calling IOCTL set control for"
5899         "id=%x, val=%d id=%x, val=%d"
5900         "id=%x, val=%d id=%x, val=%d"
5901         "id=%x, val=%d id=%x, val=%d",
5902         controls.controls[0].id, controls.controls[0].value,
5903         controls.controls[1].id, controls.controls[1].value,
5904         controls.controls[2].id, controls.controls[2].value,
5905         controls.controls[3].id, controls.controls[3].value,
5906         controls.controls[4].id, controls.controls[4].value,
5907         controls.controls[5].id, controls.controls[5].value);
5908 
5909     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5910     if (rc) {
5911         DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
5912         return false;
5913     }
5914     return true;
5915 }
5916 
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)5917 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
5918 {
5919     bool status = true;
5920     struct v4l2_control control;
5921     int rc = 0;
5922     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
5923 
5924     switch (eControlRate) {
5925         case OMX_Video_ControlRateDisable:
5926             control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
5927             break;
5928         case OMX_Video_ControlRateVariableSkipFrames:
5929             (supported_rc_modes & RC_VBR_VFR) ?
5930                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
5931                 status = false;
5932             break;
5933         case OMX_Video_ControlRateVariable:
5934             (supported_rc_modes & RC_VBR_CFR) ?
5935                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
5936                 status = false;
5937             break;
5938         case OMX_Video_ControlRateConstantSkipFrames:
5939             (supported_rc_modes & RC_CBR_VFR) ?
5940                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
5941                 status = false;
5942             break;
5943         case OMX_Video_ControlRateConstant:
5944             (supported_rc_modes & RC_CBR_CFR) ?
5945                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
5946                 status = false;
5947             break;
5948         default:
5949             status = false;
5950             break;
5951     }
5952 
5953     if (status) {
5954 
5955         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5956         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5957 
5958         if (rc) {
5959             DEBUG_PRINT_ERROR("Failed to set control");
5960             return false;
5961         }
5962 
5963         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5964 
5965         rate_ctrl.rcmode = control.value;
5966     }
5967 
5968 #ifdef _VQZIP_
5969     if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
5970         && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5971         /* Enable VQZIP SEI by default for camcorder RC modes */
5972 
5973         control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
5974         control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
5975         DEBUG_PRINT_HIGH("Set VQZIP SEI:");
5976         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
5977             DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
5978         }
5979     }
5980 #endif //_VQZIP_
5981 
5982     return status;
5983 }
5984 
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)5985 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
5986 {
5987     bool status = true;
5988     struct v4l2_control control;
5989     int rc = 0;
5990     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
5991 
5992     switch (ePerfLevel) {
5993     case OMX_QCOM_PerfLevelNominal:
5994         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
5995         break;
5996     case OMX_QCOM_PerfLevelTurbo:
5997         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
5998         break;
5999     default:
6000         status = false;
6001         break;
6002     }
6003 
6004     if (status) {
6005         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6006         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6007 
6008         if (rc) {
6009             DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
6010             return false;
6011         }
6012 
6013         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6014     }
6015     return status;
6016 }
6017 
venc_set_perf_mode(OMX_U32 mode)6018 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
6019 {
6020     struct v4l2_control control;
6021     if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
6022         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
6023         control.value = mode;
6024         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6025         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6026             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6027             return false;
6028         }
6029         return true;
6030     } else {
6031         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
6032         return false;
6033     }
6034 }
6035 
venc_set_qp(OMX_U32 nQp)6036 bool venc_dev::venc_set_qp(OMX_U32 nQp)
6037 {
6038     struct v4l2_control control;
6039     if (nQp) {
6040         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
6041         control.value = nQp;
6042         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6043         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6044             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6045             return false;
6046         }
6047     } else {
6048         DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
6049         return false;
6050     }
6051     return true;
6052 }
6053 
venc_set_aspectratio(void * nSar)6054 bool venc_dev::venc_set_aspectratio(void *nSar)
6055 {
6056     int rc;
6057     struct v4l2_control control;
6058     struct v4l2_ext_control ctrl[2];
6059     struct v4l2_ext_controls controls;
6060     QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
6061 
6062     sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
6063 
6064     ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
6065     ctrl[0].value = sar->nSARWidth;
6066     ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
6067     ctrl[1].value = sar->nSARHeight;
6068 
6069     controls.count = 2;
6070     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
6071     controls.controls = ctrl;
6072 
6073     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
6074                     controls.controls[0].id, controls.controls[0].value,
6075                     controls.controls[1].id, controls.controls[1].value);
6076 
6077     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
6078     if (rc) {
6079         DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
6080         return false;
6081     }
6082 
6083     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
6084                     controls.controls[0].id, controls.controls[0].value,
6085                     controls.controls[1].id, controls.controls[1].value);
6086     return true;
6087 }
6088 
venc_set_hierp_layers(OMX_U32 hierp_layers)6089 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
6090 {
6091     struct v4l2_control control;
6092     if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
6093             (hierp_layers <= hier_layers.numlayers)) {
6094         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6095         control.value = hierp_layers - 1;
6096         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
6097         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6098             DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
6099             return false;
6100         }
6101         return true;
6102     } else {
6103         DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
6104                 hierp_layers);
6105         return false;
6106     }
6107 }
6108 
venc_set_baselayerid(OMX_U32 baseid)6109 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
6110 {
6111     struct v4l2_control control;
6112     if (hier_layers.hier_mode == HIER_P) {
6113         control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
6114         control.value = baseid;
6115         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6116         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6117             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6118             return false;
6119         }
6120         return true;
6121     } else {
6122         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
6123                 hier_layers.hier_mode);
6124         return false;
6125     }
6126 }
6127 
venc_set_vui_timing_info(OMX_BOOL enable)6128 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
6129 {
6130     struct v4l2_control control;
6131     int rc = 0;
6132     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
6133 
6134     if (enable)
6135         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
6136     else
6137         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
6138 
6139     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
6140     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6141     if (rc) {
6142         DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
6143         return false;
6144     }
6145     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
6146     return true;
6147 }
6148 
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)6149 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
6150 {
6151     struct v4l2_control control;
6152     int rc = 0;
6153     control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
6154     control.value = nPeakBitrate;
6155 
6156     DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
6157 
6158     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6159     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6160 
6161     if (rc) {
6162         DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
6163         return false;
6164     }
6165 
6166     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6167 
6168     return true;
6169 }
6170 
venc_set_vpx_error_resilience(OMX_BOOL enable)6171 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
6172 {
6173     struct v4l2_control control;
6174     int rc = 0;
6175     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
6176 
6177     if (enable)
6178         control.value = 1;
6179     else
6180         control.value = 0;
6181 
6182     DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
6183 
6184     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6185 
6186     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6187     if (rc) {
6188         DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
6189         return false;
6190     }
6191     vpx_err_resilience.enable = 1;
6192     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6193     return true;
6194 }
6195 
venc_set_priority(OMX_U32 priority)6196 bool venc_dev::venc_set_priority(OMX_U32 priority) {
6197     struct v4l2_control control;
6198 
6199     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
6200     if (priority == 0)
6201         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
6202     else
6203         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
6204 
6205     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6206         DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
6207                 priority == 0 ? "ENABLE" : "DISABLE");
6208         return false;
6209     }
6210     return true;
6211 }
6212 
venc_set_operatingrate(OMX_U32 rate)6213 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
6214     struct v4l2_control control;
6215 
6216     control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
6217     control.value = rate;
6218 
6219     DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
6220     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6221 
6222     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6223         hw_overload = errno == EBUSY;
6224         DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
6225                 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
6226         return false;
6227     }
6228     operating_rate = rate;
6229     DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  rate >> 16);
6230     return true;
6231 }
6232 
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)6233 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
6234     char *userptr;
6235     int fd;
6236     unsigned offset;
6237     ssize_t size;
6238     struct msm_vidc_roi_qp_payload *roiData;
6239     if (!roiInfo) {
6240         DEBUG_PRINT_ERROR("No ROI info present");
6241         return false;
6242     }
6243     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
6244         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
6245         DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
6246         return false;
6247     }
6248 
6249     venc_roiqp_log_buffers(roiInfo);
6250     mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
6251     if (!userptr || size < roiInfo->nRoiMBInfoSize) {
6252         DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
6253         return false;
6254     }
6255 
6256     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
6257     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
6258     data->nVersion.nVersion = OMX_SPEC_VERSION;
6259     data->nPortIndex = 0;
6260     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
6261     data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
6262 
6263     roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
6264     roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
6265     roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
6266     roiData->b_roi_info = roiInfo->bUseRoiInfo;
6267     roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
6268     memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
6269 
6270     data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
6271     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
6272     data->nVersion.nVersion = OMX_SPEC_VERSION;
6273     data->nPortIndex = 0;
6274     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
6275     data->nDataSize = 0;
6276     return true;
6277 }
6278 
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)6279 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
6280         OMX_U32 *nMaxBLayers) {
6281 
6282     // no B-layers for all cases
6283     temporal_layers_config.nMaxBLayers = 0;
6284     temporal_layers_config.nMaxLayers = 1;
6285 
6286     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6287             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6288         temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
6289     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6290         temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
6291     }
6292 
6293     *nMaxLayers = temporal_layers_config.nMaxLayers;
6294     *nMaxBLayers = temporal_layers_config.nMaxBLayers;
6295     return true;
6296 }
6297 
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)6298 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
6299         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
6300 
6301     if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6302             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
6303             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
6304         DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
6305         return OMX_ErrorUnsupportedSetting;
6306     }
6307 
6308     if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
6309             (pTemporalParams->nBLayerCountActual != 0 ||
6310              pTemporalParams->nPLayerCountActual != 1)) {
6311         return OMX_ErrorBadParameter;
6312     } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
6313             pTemporalParams->nPLayerCountActual < 1) {
6314         return OMX_ErrorBadParameter;
6315     }
6316 
6317     if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
6318         DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
6319                 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
6320         return OMX_ErrorBadParameter;
6321     } else if (pTemporalParams->nPLayerCountActual >
6322              temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
6323         DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
6324                 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
6325                 temporal_layers_config.nMaxLayers);
6326         return OMX_ErrorBadParameter;
6327     }
6328 
6329     // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
6330     // use hybrid-HP for best results
6331     bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
6332     bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
6333     bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
6334 
6335     // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
6336     bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
6337 
6338     DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
6339             rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
6340 
6341     if (bUseHybridMode &&
6342             !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
6343                 pTemporalParams->nBLayerCountActual,
6344                 0 /* LTR count */, (int) HIER_P_HYBRID)) {
6345         bUseHybridMode = false;
6346         DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
6347     }
6348 
6349     if (intra_period.num_bframes) {
6350         DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
6351         return OMX_ErrorUnsupportedSetting;
6352     }
6353 
6354     if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
6355         DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
6356                 intra_period.num_pframes, intra_period.num_bframes);
6357         return OMX_ErrorUnsupportedSetting;
6358     }
6359 
6360     struct v4l2_control control;
6361     // Num enhancements layers does not include the base-layer
6362     control.value = pTemporalParams->nPLayerCountActual - 1;
6363 
6364     if (bUseHybridMode) {
6365         DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
6366         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6367         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6368             bUseHybridMode = false;
6369             DEBUG_PRINT_ERROR("Failed to set hybrid HP");
6370         } else {
6371             // Disable normal HP if Hybrid mode is being enabled
6372             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6373             control.value = 0;
6374             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6375                 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6376                 return OMX_ErrorUnsupportedSetting;
6377             }
6378             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6379             control.value = 0;
6380             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6381                 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
6382                 return OMX_ErrorUnsupportedSetting;
6383             }
6384         }
6385     }
6386 
6387     if (!bUseHybridMode) {
6388 
6389         // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
6390         if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
6391             DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
6392             return OMX_ErrorUnsupportedSetting;
6393         }
6394 
6395         DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
6396         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6397         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6398             DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
6399             return OMX_ErrorUnsupportedSetting;
6400         }
6401 
6402         // configure max layers for a session.. Okay to use current num-layers as max
6403         //  since we do not plan to support dynamic changes to number of layers
6404         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6405         control.value = pTemporalParams->nPLayerCountActual - 1;
6406         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6407             DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6408             return OMX_ErrorUnsupportedSetting;
6409 
6410         } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
6411             // Disable hybrid mode if it was enabled already
6412             DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
6413             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6414             control.value = 0;
6415             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6416                 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
6417                 return OMX_ErrorUnsupportedSetting;
6418             }
6419         }
6420     }
6421 
6422     // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
6423     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6424         DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
6425         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
6426         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
6427         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6428             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
6429             return OMX_ErrorUnsupportedSetting;
6430         }
6431     }
6432 
6433     temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
6434     temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
6435     temporal_layers_config.nBLayers = 0;
6436 
6437     temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
6438     if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
6439         DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
6440         return OMX_ErrorNone;
6441     }
6442     DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
6443 
6444     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
6445             numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
6446 
6447     OMX_U32 i = 0;
6448     for (; i < numLayers; ++i) {
6449         OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
6450         OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
6451         if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
6452             DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
6453             return OMX_ErrorBadParameter;
6454         } else {
6455             layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
6456             temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
6457             temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
6458             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
6459                     i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
6460         }
6461     }
6462 
6463     temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
6464 
6465     // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
6466     if (bitrate.target_bitrate > 0) {
6467         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
6468             return OMX_ErrorUnsupportedSetting;
6469         }
6470     } else {
6471         DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
6472     }
6473 
6474     return OMX_ErrorNone;
6475 }
6476 
venc_set_temporal_layers_internal()6477 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
6478     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
6479     memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
6480 
6481     if (!temporal_layers_config.nPLayers) {
6482         return OMX_ErrorNone;
6483     }
6484     pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6485     pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
6486     pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
6487     pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6488     pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
6489     pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
6490     pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
6491     if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
6492         for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
6493             pTemporalParams.nBitrateRatios[i] =
6494                     temporal_layers_config.nTemporalLayerBitrateRatio[i];
6495         }
6496     }
6497     return venc_set_temporal_layers(&pTemporalParams);
6498 }
6499 
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6500 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
6501 {
6502     bool status = true;
6503 
6504     if (eProfile == NULL || eLevel == NULL) {
6505         return false;
6506     }
6507 
6508     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6509         switch (codec_profile.profile) {
6510             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6511                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6512                 break;
6513             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6514                 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6515                 break;
6516             default:
6517                 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
6518                 status = false;
6519                 break;
6520         }
6521 
6522         if (!status) {
6523             return status;
6524         }
6525 
6526         //profile level
6527         switch (profile_level.level) {
6528             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
6529                 *eLevel = OMX_VIDEO_MPEG4Level0;
6530                 break;
6531             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
6532                 *eLevel = OMX_VIDEO_MPEG4Level0b;
6533                 break;
6534             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
6535                 *eLevel = OMX_VIDEO_MPEG4Level1;
6536                 break;
6537             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
6538                 *eLevel = OMX_VIDEO_MPEG4Level2;
6539                 break;
6540             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
6541                 *eLevel = OMX_VIDEO_MPEG4Level3;
6542                 break;
6543             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
6544                 *eLevel = OMX_VIDEO_MPEG4Level4;
6545                 break;
6546             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
6547                 *eLevel = OMX_VIDEO_MPEG4Level5;
6548                 break;
6549             default:
6550                 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6551                 status =  false;
6552                 break;
6553         }
6554     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6555         if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
6556             *eProfile = OMX_VIDEO_H263ProfileBaseline;
6557         } else {
6558             *eProfile = OMX_VIDEO_H263ProfileMax;
6559             return false;
6560         }
6561 
6562         switch (profile_level.level) {
6563             case VEN_LEVEL_H263_10:
6564                 *eLevel = OMX_VIDEO_H263Level10;
6565                 break;
6566             case VEN_LEVEL_H263_20:
6567                 *eLevel = OMX_VIDEO_H263Level20;
6568                 break;
6569             case VEN_LEVEL_H263_30:
6570                 *eLevel = OMX_VIDEO_H263Level30;
6571                 break;
6572             case VEN_LEVEL_H263_40:
6573                 *eLevel = OMX_VIDEO_H263Level40;
6574                 break;
6575             case VEN_LEVEL_H263_45:
6576                 *eLevel = OMX_VIDEO_H263Level45;
6577                 break;
6578             case VEN_LEVEL_H263_50:
6579                 *eLevel = OMX_VIDEO_H263Level50;
6580                 break;
6581             case VEN_LEVEL_H263_60:
6582                 *eLevel = OMX_VIDEO_H263Level60;
6583                 break;
6584             case VEN_LEVEL_H263_70:
6585                 *eLevel = OMX_VIDEO_H263Level70;
6586                 break;
6587             default:
6588                 *eLevel = OMX_VIDEO_H263LevelMax;
6589                 status = false;
6590                 break;
6591         }
6592     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6593         switch (codec_profile.profile) {
6594             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6595                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6596                 break;
6597             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6598                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6599                 break;
6600             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6601                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6602                 break;
6603             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6604                 *eProfile = OMX_VIDEO_AVCProfileMain;
6605                 break;
6606             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6607                 *eProfile = OMX_VIDEO_AVCProfileHigh;
6608                 break;
6609             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6610                 *eProfile = OMX_VIDEO_AVCProfileExtended;
6611                 break;
6612             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6613                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6614                 break;
6615             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6616                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6617                 break;
6618             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6619                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6620                 break;
6621             default:
6622                 *eProfile = OMX_VIDEO_AVCProfileMax;
6623                 status = false;
6624                 break;
6625         }
6626 
6627         if (!status) {
6628             return status;
6629         }
6630 
6631         switch (profile_level.level) {
6632             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
6633                 *eLevel = OMX_VIDEO_AVCLevel1;
6634                 break;
6635             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
6636                 *eLevel = OMX_VIDEO_AVCLevel1b;
6637                 break;
6638             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
6639                 *eLevel = OMX_VIDEO_AVCLevel11;
6640                 break;
6641             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
6642                 *eLevel = OMX_VIDEO_AVCLevel12;
6643                 break;
6644             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
6645                 *eLevel = OMX_VIDEO_AVCLevel13;
6646                 break;
6647             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
6648                 *eLevel = OMX_VIDEO_AVCLevel2;
6649                 break;
6650             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
6651                 *eLevel = OMX_VIDEO_AVCLevel21;
6652                 break;
6653             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
6654                 *eLevel = OMX_VIDEO_AVCLevel22;
6655                 break;
6656             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
6657                 *eLevel = OMX_VIDEO_AVCLevel3;
6658                 break;
6659             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
6660                 *eLevel = OMX_VIDEO_AVCLevel31;
6661                 break;
6662             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
6663                 *eLevel = OMX_VIDEO_AVCLevel32;
6664                 break;
6665             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
6666                 *eLevel = OMX_VIDEO_AVCLevel4;
6667                 break;
6668             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
6669                 *eLevel = OMX_VIDEO_AVCLevel41;
6670                 break;
6671             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
6672                 *eLevel = OMX_VIDEO_AVCLevel42;
6673                 break;
6674             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
6675                 *eLevel = OMX_VIDEO_AVCLevel5;
6676                 break;
6677             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
6678                 *eLevel = OMX_VIDEO_AVCLevel51;
6679                 break;
6680             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
6681                 *eLevel = OMX_VIDEO_AVCLevel52;
6682                 break;
6683             default :
6684                 *eLevel = OMX_VIDEO_AVCLevelMax;
6685                 status = false;
6686                 break;
6687         }
6688     }
6689     else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6690         switch (codec_profile.profile) {
6691             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6692                 *eProfile = OMX_VIDEO_VP8ProfileMain;
6693                 break;
6694             default:
6695                 *eProfile = OMX_VIDEO_VP8ProfileMax;
6696                 status = false;
6697                 break;
6698         }
6699         if (!status) {
6700             return status;
6701         }
6702 
6703         switch (profile_level.level) {
6704             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6705                 *eLevel = OMX_VIDEO_VP8Level_Version0;
6706                 break;
6707             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6708                 *eLevel = OMX_VIDEO_VP8Level_Version1;
6709                 break;
6710             default:
6711                 *eLevel = OMX_VIDEO_VP8LevelMax;
6712                 status = false;
6713                 break;
6714         }
6715     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6716         switch (codec_profile.profile) {
6717             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6718                 *eProfile = OMX_VIDEO_HEVCProfileMain;
6719                 break;
6720             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6721                 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6722                 break;
6723             default:
6724                 *eProfile = OMX_VIDEO_HEVCProfileMax;
6725                 status = false;
6726                 break;
6727         }
6728         if (!status) {
6729             return status;
6730         }
6731 
6732         switch (profile_level.level) {
6733             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
6734                 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
6735                 break;
6736             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
6737                 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
6738                 break;
6739             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
6740                 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
6741                 break;
6742             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
6743                 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
6744                 break;
6745             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
6746                 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
6747                 break;
6748             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
6749                 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
6750                 break;
6751             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
6752                 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
6753                 break;
6754             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
6755                 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
6756                 break;
6757             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
6758                 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
6759                 break;
6760             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
6761                 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
6762                 break;
6763             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
6764                 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
6765                 break;
6766             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
6767                 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
6768                 break;
6769             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
6770                 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
6771                 break;
6772             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
6773                 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
6774                 break;
6775             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
6776                 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
6777                 break;
6778             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
6779                 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
6780                 break;
6781             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
6782                 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
6783                 break;
6784             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
6785                 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
6786                 break;
6787             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
6788                 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
6789                 break;
6790             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
6791                 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
6792                 break;
6793             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
6794                 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
6795                 break;
6796             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
6797                 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
6798                 break;
6799             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
6800                 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
6801                 break;
6802             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
6803                 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
6804                 break;
6805             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
6806                 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
6807                 break;
6808             default:
6809                 *eLevel = OMX_VIDEO_HEVCLevelMax;
6810                 status = false;
6811                 break;
6812         }
6813     }
6814 
6815     return status;
6816 }
6817 
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6818 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
6819 {
6820     OMX_U32 new_profile = 0, new_level = 0;
6821     unsigned const int *profile_tbl = NULL;
6822     OMX_U32 mb_per_frame, mb_per_sec;
6823     bool profile_level_found = false;
6824 
6825     DEBUG_PRINT_LOW("Init profile table for respective codec");
6826 
6827     //validate the ht,width,fps,bitrate and set the appropriate profile and level
6828     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6829         if (*eProfile == 0) {
6830             if (!m_profile_set) {
6831                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6832             } else {
6833                 switch (codec_profile.profile) {
6834                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6835                         *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6836                         break;
6837                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6838                         *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6839                         break;
6840                     default:
6841                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6842                         return false;
6843                 }
6844             }
6845         }
6846 
6847         if (*eLevel == 0 && !m_level_set) {
6848             *eLevel = OMX_VIDEO_MPEG4LevelMax;
6849         }
6850 
6851         if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
6852             profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
6853         } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
6854             profile_tbl = (unsigned int const *)
6855                 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
6856         } else {
6857             DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
6858             return false;
6859         }
6860     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6861         if (*eProfile == 0) {
6862             if (!m_profile_set) {
6863                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6864             } else {
6865                 switch (codec_profile.profile) {
6866                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6867                         *eProfile = OMX_VIDEO_AVCProfileBaseline;
6868                         break;
6869                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6870                         *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6871                         break;
6872                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6873                          *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6874                         break;
6875                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6876                         *eProfile = OMX_VIDEO_AVCProfileMain;
6877                         break;
6878                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6879                         *eProfile = OMX_VIDEO_AVCProfileExtended;
6880                         break;
6881                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6882                         *eProfile = OMX_VIDEO_AVCProfileHigh;
6883                         break;
6884                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6885                         *eProfile = OMX_VIDEO_AVCProfileHigh10;
6886                         break;
6887                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6888                         *eProfile = OMX_VIDEO_AVCProfileHigh422;
6889                         break;
6890                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6891                         *eProfile = OMX_VIDEO_AVCProfileHigh444;
6892                         break;
6893                     default:
6894                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6895                         return false;
6896                 }
6897             }
6898         }
6899 
6900         if (*eLevel == 0 && !m_level_set) {
6901             *eLevel = OMX_VIDEO_AVCLevelMax;
6902         }
6903 
6904         if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
6905             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
6906             profile_tbl = (unsigned int const *)h264_profile_level_table;
6907         } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
6908             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
6909             profile_tbl = (unsigned int const *)
6910                 (&h264_profile_level_table[H264_HP_START]);
6911         } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
6912             profile_tbl = (unsigned int const *)
6913                 (&h264_profile_level_table[H264_MP_START]);
6914         } else {
6915             DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
6916             return false;
6917         }
6918     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6919         if (*eProfile == 0) {
6920             if (!m_profile_set) {
6921                 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6922             } else {
6923                 switch (codec_profile.profile) {
6924                     case VEN_PROFILE_H263_BASELINE:
6925                         *eProfile = OMX_VIDEO_H263ProfileBaseline;
6926                         break;
6927                     default:
6928                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6929                         return false;
6930                 }
6931             }
6932         }
6933 
6934         if (*eLevel == 0 && !m_level_set) {
6935             *eLevel = OMX_VIDEO_H263LevelMax;
6936         }
6937 
6938         if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
6939             profile_tbl = (unsigned int const *)h263_profile_level_table;
6940         } else {
6941             DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
6942             return false;
6943         }
6944     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6945         if (*eProfile == 0) {
6946             *eProfile = OMX_VIDEO_VP8ProfileMain;
6947         } else {
6948             switch (codec_profile.profile) {
6949                 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6950                     *eProfile = OMX_VIDEO_VP8ProfileMain;
6951                     break;
6952                 default:
6953                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
6954                     return false;
6955             }
6956         }
6957         if (*eLevel == 0) {
6958             switch (profile_level.level) {
6959                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6960                     *eLevel = OMX_VIDEO_VP8Level_Version0;
6961                     break;
6962                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6963                     *eLevel = OMX_VIDEO_VP8Level_Version1;
6964                     break;
6965                 default:
6966                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
6967                     return false;
6968             }
6969         }
6970         return true;
6971     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6972         if (*eProfile == 0) {
6973             if (!m_profile_set) {
6974                 *eProfile = OMX_VIDEO_HEVCProfileMain;
6975             } else {
6976                 switch (codec_profile.profile) {
6977                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6978                         *eProfile = OMX_VIDEO_HEVCProfileMain;
6979                         break;
6980                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6981                         *eProfile = OMX_VIDEO_HEVCProfileMain10;
6982                         break;
6983                     default:
6984                         DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
6985                         return false;
6986                 }
6987             }
6988         }
6989 
6990         if (*eLevel == 0 && !m_level_set) {
6991             *eLevel = OMX_VIDEO_HEVCLevelMax;
6992         }
6993 
6994         if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
6995             profile_tbl = (unsigned int const *)hevc_profile_level_table;
6996         } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
6997             profile_tbl = (unsigned int const *)
6998                 (&hevc_profile_level_table[HEVC_MAIN10_START]);
6999         } else {
7000             DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
7001             return false;
7002         }
7003     } else {
7004         DEBUG_PRINT_ERROR("Invalid codec type");
7005         return false;
7006     }
7007 
7008     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
7009         ((m_sVenc_cfg.dvs_width + 15)>> 4);
7010 
7011     if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
7012         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
7013             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7014 
7015         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
7016             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7017 
7018         {
7019             new_level = profile_level.level;
7020             new_profile = codec_profile.profile;
7021             return true;
7022         }
7023     }
7024 
7025     if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
7026         *eLevel = rc_off_level; //No level calculation for RC_OFF
7027         profile_level_found = true;
7028         return true;
7029     }
7030 
7031     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
7032 
7033     bool h264, ltr, hlayers;
7034     unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
7035     h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
7036     ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7037     hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
7038      ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
7039 
7040     /*  Hybrid HP reference buffers:
7041         layers = 1, 2 need 1 reference buffer
7042         layers = 3, 4 need 2 reference buffers
7043         layers = 5, 6 need 3 reference buffers
7044     */
7045 
7046     if(hier_layers.hier_mode == HIER_P_HYBRID)
7047         hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
7048 
7049     do {
7050         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
7051             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
7052                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
7053                     if (h264 && (ltr || hlayers || hybridp)) {
7054                         // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
7055                         new_level = (int)profile_tbl[3];
7056                         new_profile = (int)profile_tbl[4];
7057                         profile_level_found = true;
7058                         DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
7059                                         ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
7060                                         MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7061                         break;
7062                     } else {
7063                         new_level = (int)profile_tbl[3];
7064                         new_profile = (int)profile_tbl[4];
7065                         profile_level_found = true;
7066                         DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
7067                         break;
7068                     }
7069                 }
7070             }
7071         }
7072         profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
7073     } while (profile_tbl[0] != 0);
7074 
7075     if (profile_level_found != true) {
7076         DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
7077         return false;
7078     }
7079 
7080     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
7081             || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
7082             || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
7083         *eLevel = new_level;
7084     }
7085 
7086     DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
7087             "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
7088 
7089     return true;
7090 }
7091 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)7092 bool venc_dev::venc_set_meta_mode(bool mode)
7093 {
7094     metadatamode = mode;
7095     return true;
7096 }
7097 #endif
7098 
venc_is_video_session_supported(unsigned long width,unsigned long height)7099 bool venc_dev::venc_is_video_session_supported(unsigned long width,
7100         unsigned long height)
7101 {
7102     if ((width * height < capability.min_width *  capability.min_height) ||
7103             (width * height > capability.max_width *  capability.max_height)) {
7104         DEBUG_PRINT_ERROR(
7105                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
7106                 width, height, capability.min_width, capability.min_height,
7107                 capability.max_width, capability.max_height);
7108         return false;
7109     }
7110 
7111     DEBUG_PRINT_LOW("video session supported");
7112     return true;
7113 }
7114 
venc_set_batch_size(OMX_U32 batchSize)7115 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
7116 {
7117     struct v4l2_control control;
7118     int ret;
7119 
7120     control.id = V4L2_CID_VIDC_QBUF_MODE;
7121     control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
7122 
7123     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
7124     if (ret) {
7125         DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
7126         return false;
7127     }
7128 
7129     mBatchSize = batchSize;
7130     DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
7131     return true;
7132 }
7133 
BatchInfo()7134 venc_dev::BatchInfo::BatchInfo()
7135     : mNumPending(0) {
7136     pthread_mutex_init(&mLock, NULL);
7137     for (int i = 0; i < kMaxBufs; ++i) {
7138         mBufMap[i] = kBufIDFree;
7139     }
7140 }
7141 
registerBuffer(int bufferId)7142 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
7143     pthread_mutex_lock(&mLock);
7144     int availId = 0;
7145     for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
7146     if (availId >= kMaxBufs) {
7147         DEBUG_PRINT_ERROR("Failed to find free entry !");
7148         pthread_mutex_unlock(&mLock);
7149         return -1;
7150     }
7151     mBufMap[availId] = bufferId;
7152     mNumPending++;
7153     pthread_mutex_unlock(&mLock);
7154     return availId;
7155 }
7156 
retrieveBufferAt(int v4l2Id)7157 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
7158     pthread_mutex_lock(&mLock);
7159     if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
7160         DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
7161         pthread_mutex_unlock(&mLock);
7162         return -1;
7163     }
7164     if (mBufMap[v4l2Id] == kBufIDFree) {
7165         DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
7166         pthread_mutex_unlock(&mLock);
7167         return -1;
7168     }
7169     int bufferId = mBufMap[v4l2Id];
7170     mBufMap[v4l2Id] = kBufIDFree;
7171     mNumPending--;
7172     pthread_mutex_unlock(&mLock);
7173     return bufferId;
7174 }
7175 
isPending(int bufferId)7176 bool venc_dev::BatchInfo::isPending(int bufferId) {
7177     pthread_mutex_lock(&mLock);
7178     int existsId = 0;
7179     for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
7180     pthread_mutex_unlock(&mLock);
7181     return existsId < kMaxBufs;
7182 }
7183 
getFdAt(native_handle_t * hnd,int index)7184 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
7185     int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
7186     return fd;
7187 }
7188 
getOffsetAt(native_handle_t * hnd,int index)7189 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
7190     int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
7191     return off;
7192 }
7193 
getSizeAt(native_handle_t * hnd,int index)7194 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
7195     int size = hnd && (index + hnd->numFds) < hnd->numInts ?
7196             hnd->data[2*hnd->numFds + index] : -1;
7197     return size;
7198 }
7199 
getColorFormatAt(native_handle_t * hnd,int index)7200 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
7201     int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
7202             hnd->data[3*hnd->numFds + index] : 0;
7203     return usage;
7204 }
7205 
getTimeStampAt(native_handle_t * hnd,int index)7206 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
7207     int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
7208             hnd->data[4*hnd->numFds + index] : -1;
7209     return size;
7210 }
7211 
7212 #ifdef _VQZIP_
venc_dev_vqzip()7213 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
7214 {
7215     mLibHandle = NULL;
7216     pthread_mutex_init(&lock, NULL);
7217 }
7218 
init()7219 bool venc_dev::venc_dev_vqzip::init()
7220 {
7221     bool status = true;
7222     if (mLibHandle) {
7223         DEBUG_PRINT_ERROR("VQZIP init called twice");
7224         status = false;
7225     }
7226     if (status) {
7227         mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
7228         if (mLibHandle) {
7229             mVQZIPInit = (vqzip_init_t)
7230                 dlsym(mLibHandle,"VQZipInit");
7231             mVQZIPDeInit = (vqzip_deinit_t)
7232                 dlsym(mLibHandle,"VQZipDeInit");
7233             mVQZIPComputeStats = (vqzip_compute_stats_t)
7234                 dlsym(mLibHandle,"VQZipComputeStats");
7235             if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
7236                 status = false;
7237         } else {
7238             DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
7239             status = false;
7240         }
7241         if (status) {
7242             mVQZIPHandle = mVQZIPInit();
7243         }
7244     }
7245     if (!status && mLibHandle) {
7246         dlclose(mLibHandle);
7247         mLibHandle = NULL;
7248         mVQZIPHandle = NULL;
7249         mVQZIPInit = NULL;
7250         mVQZIPDeInit = NULL;
7251         mVQZIPComputeStats = NULL;
7252     }
7253     return status;
7254 }
7255 
fill_stats_data(void * pBuf,void * extraData)7256 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
7257 {
7258     VQZipStatus result;
7259     VQZipStats *pStats = (VQZipStats *)extraData;
7260     pConfig.pSEIPayload = NULL;
7261     unsigned long size;
7262 
7263     if (!pBuf || !pStats || !mVQZIPHandle) {
7264         DEBUG_PRINT_ERROR("Invalid data passed to stats function");
7265     }
7266     result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
7267     return (result < 0);
7268 }
7269 
deinit()7270 void venc_dev::venc_dev_vqzip::deinit()
7271 {
7272     if (mLibHandle) {
7273         pthread_mutex_lock(&lock);
7274         dlclose(mLibHandle);
7275         mVQZIPDeInit(mVQZIPHandle);
7276         mLibHandle = NULL;
7277         mVQZIPHandle = NULL;
7278         mVQZIPInit = NULL;
7279         mVQZIPDeInit = NULL;
7280         mVQZIPComputeStats = NULL;
7281         pthread_mutex_unlock(&lock);
7282     }
7283 }
7284 
~venc_dev_vqzip()7285 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
7286 {
7287     DEBUG_PRINT_HIGH("Destroy C2D instance");
7288     if (mLibHandle) {
7289         dlclose(mLibHandle);
7290     }
7291     mLibHandle = NULL;
7292     pthread_mutex_destroy(&lock);
7293 }
7294 #endif
7295 
encExtradata(class omx_venc * venc_handle)7296 encExtradata::encExtradata(class omx_venc *venc_handle)
7297 {
7298     mCount = 0;
7299     mSize = 0;
7300     mUaddr = NULL;
7301     memset(&mIon, -1, sizeof(struct venc_ion));
7302     memset(mIndex, 0, sizeof(mIndex));
7303     mVencHandle = venc_handle;
7304     mDbgEtbCount = 0;
7305     pthread_mutex_init(&lock, NULL);
7306     vqzip_sei_found = false;
7307 }
7308 
~encExtradata()7309 encExtradata::~encExtradata()
7310 {
7311     __free();
7312     mCount = 0;
7313     mSize = 0;
7314     mVencHandle = NULL;
7315     pthread_mutex_destroy(&lock);
7316 }
7317 
__allocate()7318 OMX_ERRORTYPE encExtradata::__allocate()
7319 {
7320     ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
7321     if (!mVencHandle) {
7322         return OMX_ErrorInsufficientResources;
7323     }
7324     if (mUaddr || !totalSize) {
7325         return OMX_ErrorNone;
7326     }
7327     mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
7328             totalSize,
7329             &mIon.ion_alloc_data,
7330             &mIon.fd_ion_data, 0);
7331     if (mIon.ion_device_fd < 0) {
7332         DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
7333         DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
7334         return OMX_ErrorInsufficientResources;
7335     }
7336     mUaddr = (char *)mmap(NULL, totalSize,
7337             PROT_READ|PROT_WRITE, MAP_SHARED,
7338             mIon.fd_ion_data.fd , 0);
7339     if (mUaddr == MAP_FAILED) {
7340         DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
7341         close(mIon.fd_ion_data.fd);
7342         mVencHandle->free_ion_memory(&mIon);
7343         return OMX_ErrorInsufficientResources;
7344     }
7345     for (unsigned i = 0; i < mCount; i++) {
7346         mIndex[i].status = FREE;
7347         mIndex[i].cookie = NULL;
7348     }
7349     return OMX_ErrorNone;
7350 }
7351 
__get(char ** userptr,int * fd,unsigned * offset,ssize_t * size,int type)7352 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
7353 {
7354     unsigned i = 0;
7355     if (__allocate() != OMX_ErrorNone) {
7356         return -1;
7357     }
7358     for (i = 0; i < mCount; i++) {
7359         if (mIndex[i].status == type) {
7360             mIndex[i].status = BUSY;
7361             break;
7362         }
7363     }
7364     if (i >= mCount) {
7365         DEBUG_PRINT_HIGH("No Free extradata available");
7366         return -1;
7367     }
7368     *userptr = mUaddr + i * mSize;
7369     *fd = mIon.fd_ion_data.fd;
7370     *offset = i * mSize;
7371     *size = mSize;
7372     return i;
7373 }
7374 
get(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7375 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
7376     int index;
7377     *userptr = NULL;
7378     *fd = -1;
7379     *offset = 0;
7380     *size = 0;
7381     pthread_mutex_lock(&lock);
7382     index = __get(userptr, fd, offset, size, FREE);
7383     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7384     pthread_mutex_unlock(&lock);
7385     return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
7386 }
7387 
get(void * cookie,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7388 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
7389 {
7390     OMX_ERRORTYPE rc = OMX_ErrorNone;
7391     unsigned int i;
7392     *userptr = NULL;
7393     *fd = -1;
7394     *offset = 0;
7395     *size = 0;
7396     pthread_mutex_lock(&lock);
7397     for (i = 0; i < mCount; i++) {
7398         if (mIndex[i].cookie == cookie) {
7399             break;
7400         }
7401     }
7402     if (i < mCount) {
7403         *userptr = mUaddr + i * mSize;
7404         *fd = mIon.fd_ion_data.fd;
7405         *offset = i * mSize;
7406         *size = mSize;
7407     } else {
7408         int index = __get(userptr, fd, offset, size, FREE);
7409         if (index < 0 ) {
7410             DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
7411             __debug();
7412             rc = OMX_ErrorInsufficientResources;
7413         }
7414     }
7415     DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
7416     pthread_mutex_unlock(&lock);
7417     return rc;
7418 }
7419 
getForConfig(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7420 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
7421 {
7422     OMX_ERRORTYPE rc = OMX_ErrorNone;
7423     unsigned int i;
7424     int found = -1;
7425     pthread_mutex_lock(&lock);
7426     found = __get(userptr, fd, offset, size, FOR_CONFIG);
7427     if (found < 0) {
7428         found = __get(userptr, fd, offset, size, FREE);
7429     }
7430 
7431     if (found < 0) {
7432         DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
7433         __debug();
7434         rc = OMX_ErrorInsufficientResources;
7435     } else {
7436         mIndex[found].status = FOR_CONFIG;
7437         DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
7438     }
7439     pthread_mutex_unlock(&lock);
7440     return rc;
7441 }
7442 
put(char * userptr)7443 OMX_ERRORTYPE encExtradata::put(char *userptr)
7444 {
7445     OMX_ERRORTYPE rc = OMX_ErrorNone;
7446     int index = (userptr - mUaddr)/mSize;
7447     pthread_mutex_lock(&lock);
7448     if (!userptr) {
7449         DEBUG_PRINT_HIGH("Userptr is NULL");
7450         rc = OMX_ErrorBadParameter;
7451     } else if (index < 0) {
7452         DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
7453         __debug();
7454         rc = OMX_ErrorBadParameter;
7455     } else {
7456         mIndex[index].status = FREE;
7457         mIndex[index].cookie = NULL;
7458         DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
7459     }
7460     pthread_mutex_unlock(&lock);
7461     return rc;
7462 }
7463 
peek(unsigned index,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7464 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
7465 {
7466     OMX_ERRORTYPE rc = OMX_ErrorNone;
7467     *userptr = 0;
7468     *fd = -1;
7469     *offset = 0;
7470     *size = 0;
7471     pthread_mutex_lock(&lock);
7472     if (index < mCount) {
7473         rc = __allocate();
7474         if (rc == OMX_ErrorNone) {
7475             *userptr = mUaddr + index * mSize;
7476             *fd = mIon.fd_ion_data.fd;
7477             *offset = index * mSize;
7478             *size = mSize;
7479         }
7480     }
7481     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7482     pthread_mutex_unlock(&lock);
7483     return rc;
7484 }
7485 
setCookieForConfig(void * cookie)7486 void encExtradata::setCookieForConfig(void *cookie)
7487 {
7488     char *userptr;
7489     int fd;
7490     unsigned offset;
7491     ssize_t size;
7492     pthread_mutex_lock(&lock);
7493     int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
7494     if (found >= 0) {
7495         mIndex[found].cookie = cookie;
7496     } else {
7497         DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
7498             found, cookie);
7499         __debug();
7500     }
7501     mDbgEtbCount++;
7502     pthread_mutex_unlock(&lock);
7503 }
7504 
__free()7505 void encExtradata::__free()
7506 {
7507     ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
7508     if (mUaddr) {
7509         munmap((void *)mUaddr, totalSize);
7510         mUaddr = NULL;
7511     }
7512     if (mIon.fd_ion_data.fd >= 0) {
7513         if (mVencHandle)
7514             mVencHandle->free_ion_memory(&mIon);
7515         close(mIon.fd_ion_data.fd);
7516         mIon.fd_ion_data.fd = -1;
7517     }
7518     for (unsigned i = 0; i < mCount; i++) {
7519         mIndex[i].status = FREE;
7520         mIndex[i].cookie = NULL;
7521     }
7522 }
7523 
update(unsigned int count,ssize_t size)7524 void encExtradata::update(unsigned int count, ssize_t size)
7525 {
7526     pthread_mutex_lock(&lock);
7527     __free();
7528     mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
7529     mSize = size;
7530     DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
7531     pthread_mutex_unlock(&lock);
7532 }
7533 
__debug()7534 void encExtradata::__debug()
7535 {
7536     DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
7537             this, mCount, mSize, mUaddr, mVencHandle);
7538     for (unsigned i = 0; i < mCount; i++) {
7539         DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
7540     }
7541 }
7542 
getBufferSize()7543 ssize_t encExtradata::getBufferSize()
7544 {
7545     return mSize;
7546 }
7547 
getBufferCount()7548 unsigned int encExtradata::getBufferCount()
7549 {
7550     return mCount;
7551 }
7552