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