1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2015, 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 <unistd.h>
33 #include <fcntl.h>
34 #include "video_encoder_device_v4l2.h"
35 #include "omx_video_encoder.h"
36 #include <media/msm_vidc.h>
37 #ifdef USE_ION
38 #include <linux/msm_ion.h>
39 #endif
40 #include <media/msm_media_info.h>
41 #include <cutils/properties.h>
42 #include <media/hardware/HardwareAPI.h>
43 
44 #ifdef _ANDROID_
45 #include <media/hardware/HardwareAPI.h>
46 #include <gralloc_priv.h>
47 #include <qdMetaData.h>
48 #endif
49 
50 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
51 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
52 #define MAXDPB 16
53 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
54 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
55 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
56 #define MAX_PROFILE_PARAMS 6
57 #define MPEG4_SP_START 0
58 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
59 #define H263_BP_START 0
60 #define H264_BP_START 0
61 #define H264_HP_START (H264_BP_START + 17)
62 #define H264_MP_START (H264_BP_START + 34)
63 #define HEVC_MAIN_START 0
64 #define HEVC_MAIN10_START (HEVC_MAIN_START + 12)
65 #define POLL_TIMEOUT 1000
66 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
67 
68 #define SZ_4K 0x1000
69 #define SZ_1M 0x100000
70 
71 /* MPEG4 profile and level table*/
72 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
73     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
74     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
75     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
76     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
77     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
78     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
79     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
80     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
81     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
82     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
83     {0,0,0,0,0,0},
84 
85     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
86     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
87     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
88     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
89     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
90     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
91     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
92     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
93     {0,0,0,0,0,0},
94 };
95 
96 /* H264 profile and level table*/
97 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
98     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
99     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
100     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
101     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
102     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
103     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
104     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
105     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
106     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
107     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
108     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
109     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
110     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
111     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
112     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
113     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
114     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
115     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
116     {0,0,0,0,0,0},
117 
118     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
119     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
120     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
121     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
122     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
123     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
124     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
125     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
126     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
127     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
128     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
129     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
130     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
131     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
132     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
133     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
134     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
135     {0,0,0,0,0,0},
136 
137     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
138     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
139     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
140     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
141     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
142     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
143     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
144     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
145     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
146     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
147     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
148     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
149     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
150     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
151     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
152     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
153     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
154     {0,0,0,0,0,0}
155 
156 };
157 
158 /* H263 profile and level table*/
159 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
160     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
161     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
162     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
163     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
164     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
165     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
166     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
167     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
168     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
169     {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
170     {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
171     {0,0,0,0,0,0}
172 };
173 
174 /* HEVC profile and level table*/
175 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
176     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
177     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
178     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
179     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
180     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
181     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
182     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
183     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
184     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
185     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
186     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
187     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
188     {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
189     {0,0,0,0,0},
190 
191     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
192     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
193     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
194     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
195     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
196     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
197     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
198     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
199     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
200     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
201     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
202     {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
203     {0,0,0,0,0},
204 };
205 
206 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
207 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
208 
209 #define BUFFER_LOG_LOC "/data/misc/media"
210 
211 //constructor
venc_dev(class omx_venc * venc_class)212 venc_dev::venc_dev(class omx_venc *venc_class)
213 {
214     //nothing to do
215     int i = 0;
216     venc_handle = venc_class;
217     etb = ebd = ftb = fbd = 0;
218 
219     for (i = 0; i < MAX_PORT; i++)
220         streaming[i] = false;
221 
222     stopped = 1;
223     paused = false;
224     async_thread_created = false;
225     color_format = 0;
226     hw_overload = false;
227     pthread_mutex_init(&pause_resume_mlock, NULL);
228     pthread_cond_init(&pause_resume_cond, NULL);
229     memset(&extradata_info, 0, sizeof(extradata_info));
230     memset(&idrperiod, 0, sizeof(idrperiod));
231     memset(&multislice, 0, sizeof(multislice));
232     memset (&slice_mode, 0 , sizeof(slice_mode));
233     memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
234     memset(&rate_ctrl, 0, sizeof(rate_ctrl));
235     memset(&bitrate, 0, sizeof(bitrate));
236     memset(&intra_period, 0, sizeof(intra_period));
237     memset(&codec_profile, 0, sizeof(codec_profile));
238     memset(&set_param, 0, sizeof(set_param));
239     memset(&time_inc, 0, sizeof(time_inc));
240     memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
241     memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
242     memset(&session_qp, 0, sizeof(session_qp));
243     memset(&entropy, 0, sizeof(entropy));
244     memset(&dbkfilter, 0, sizeof(dbkfilter));
245     memset(&intra_refresh, 0, sizeof(intra_refresh));
246     memset(&hec, 0, sizeof(hec));
247     memset(&voptimecfg, 0, sizeof(voptimecfg));
248     memset(&capability, 0, sizeof(capability));
249     memset(&m_debug,0,sizeof(m_debug));
250     memset(&hier_layers,0,sizeof(hier_layers));
251     is_searchrange_set = false;
252     enable_mv_narrow_searchrange = false;
253     supported_rc_modes = RC_ALL;
254     camera_mode_enabled = false;
255     memset(&ltrinfo, 0, sizeof(ltrinfo));
256     sess_priority.priority = 1;
257     operating_rate = 0;
258     memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
259 
260     char property_value[PROPERTY_VALUE_MAX] = {0};
261     property_get("vidc.enc.log.in", property_value, "0");
262     m_debug.in_buffer_log = atoi(property_value);
263 
264     property_get("vidc.enc.log.out", property_value, "0");
265     m_debug.out_buffer_log = atoi(property_value);
266 
267     property_get("vidc.enc.log.extradata", property_value, "0");
268     m_debug.extradata_log = atoi(property_value);
269 
270     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
271              "%s", BUFFER_LOG_LOC);
272 }
273 
~venc_dev()274 venc_dev::~venc_dev()
275 {
276     //nothing to do
277 }
278 
async_venc_message_thread(void * input)279 void* venc_dev::async_venc_message_thread (void *input)
280 {
281     struct venc_msg venc_msg;
282     omx_video* omx_venc_base = NULL;
283     omx_venc *omx = reinterpret_cast<omx_venc*>(input);
284     omx_venc_base = reinterpret_cast<omx_video*>(input);
285     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
286 
287     prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
288     struct v4l2_plane plane[VIDEO_MAX_PLANES];
289     struct pollfd pfd;
290     struct v4l2_buffer v4l2_buf;
291     struct v4l2_event dqevent;
292     pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
293     pfd.fd = omx->handle->m_nDriver_fd;
294     int error_code = 0,rc=0;
295 
296     memset(&v4l2_buf, 0, sizeof(v4l2_buf));
297 
298     while (1) {
299         pthread_mutex_lock(&omx->handle->pause_resume_mlock);
300 
301         if (omx->handle->paused) {
302             venc_msg.msgcode = VEN_MSG_PAUSE;
303             venc_msg.statuscode = VEN_S_SUCCESS;
304 
305             if (omx->async_message_process(input, &venc_msg) < 0) {
306                 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
307                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
308                 break;
309             }
310 
311             /* Block here until the IL client resumes us again */
312             pthread_cond_wait(&omx->handle->pause_resume_cond,
313                     &omx->handle->pause_resume_mlock);
314 
315             venc_msg.msgcode = VEN_MSG_RESUME;
316             venc_msg.statuscode = VEN_S_SUCCESS;
317 
318             if (omx->async_message_process(input, &venc_msg) < 0) {
319                 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
320                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
321                 break;
322             }
323         }
324 
325         pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
326 
327         rc = poll(&pfd, 1, POLL_TIMEOUT);
328 
329         if (!rc) {
330             DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
331                     omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
332             continue;
333         } else if (rc < 0) {
334             DEBUG_PRINT_ERROR("Error while polling: %d", rc);
335             break;
336         }
337 
338         if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
339             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
340             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
341             v4l2_buf.length = omx->handle->num_planes;
342             v4l2_buf.m.planes = plane;
343 
344             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
345                 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
346                 venc_msg.statuscode=VEN_S_SUCCESS;
347                 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
348                 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
349                 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
350                 venc_msg.buf.flags = 0;
351                 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
352                 venc_msg.buf.clientdata=(void*)omxhdr;
353                 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
354 
355                 /* TODO: ideally report other types of frames as well
356                  * for now it doesn't look like IL client cares about
357                  * other types
358                  */
359                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
360                     venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
361 
362                 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
363                     venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
364 
365                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
366                     venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
367 
368                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
369                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
370 
371                 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
372                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
373 
374                 if (omxhdr->nFilledLen)
375                     venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
376 
377                 omx->handle->fbd++;
378 
379                 if (omx->async_message_process(input,&venc_msg) < 0) {
380                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
381                     break;
382                 }
383             }
384         }
385 
386         if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
387             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
388             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
389             v4l2_buf.m.planes = plane;
390             v4l2_buf.length = 1;
391 
392             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
393                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
394                 venc_msg.statuscode=VEN_S_SUCCESS;
395                 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
396                     omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
397                 else
398                     omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
399 
400                 venc_msg.buf.clientdata=(void*)omxhdr;
401                 omx->handle->ebd++;
402 
403                 if (omx->async_message_process(input,&venc_msg) < 0) {
404                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
405                     break;
406                 }
407             }
408         }
409 
410         if (pfd.revents & POLLPRI) {
411             rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
412 
413             if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
414                 DEBUG_PRINT_HIGH("CLOSE DONE");
415                 break;
416             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
417                 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
418                 venc_msg.statuscode = VEN_S_SUCCESS;
419 
420                 if (omx->async_message_process(input,&venc_msg) < 0) {
421                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
422                     break;
423                 }
424 
425                 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
426                 venc_msg.statuscode = VEN_S_SUCCESS;
427 
428                 if (omx->async_message_process(input,&venc_msg) < 0) {
429                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
430                     break;
431                 }
432             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
433                 DEBUG_PRINT_ERROR("HW Overload received");
434                 venc_msg.statuscode = VEN_S_EFAIL;
435                 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
436 
437                 if (omx->async_message_process(input,&venc_msg) < 0) {
438                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
439                     break;
440                 }
441             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
442                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
443                 venc_msg.msgcode = VEN_MSG_INDICATION;
444                 venc_msg.statuscode=VEN_S_EFAIL;
445 
446                 if (omx->async_message_process(input,&venc_msg) < 0) {
447                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
448                     break;
449                 }
450             }
451         }
452     }
453 
454     DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
455     return NULL;
456 }
457 
458 static const int event_type[] = {
459     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
460     V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
461     V4L2_EVENT_MSM_VIDC_SYS_ERROR
462 };
463 
subscribe_to_events(int fd)464 static OMX_ERRORTYPE subscribe_to_events(int fd)
465 {
466     OMX_ERRORTYPE eRet = OMX_ErrorNone;
467     struct v4l2_event_subscription sub;
468     int array_sz = sizeof(event_type)/sizeof(int);
469     int i,rc;
470     memset(&sub, 0, sizeof(sub));
471 
472     if (fd < 0) {
473        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
474         return OMX_ErrorBadParameter;
475     }
476 
477     for (i = 0; i < array_sz; ++i) {
478         memset(&sub, 0, sizeof(sub));
479         sub.type = event_type[i];
480         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
481 
482         if (rc) {
483            DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
484             break;
485         }
486     }
487 
488     if (i < array_sz) {
489         for (--i; i >=0 ; i--) {
490             memset(&sub, 0, sizeof(sub));
491             sub.type = event_type[i];
492             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
493 
494             if (rc)
495                DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
496         }
497 
498         eRet = OMX_ErrorNotImplemented;
499     }
500 
501     return eRet;
502 }
503 
append_mbi_extradata(void * dst,struct msm_vidc_extradata_header * src)504 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
505 {
506     OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
507 
508     if (!dst || !src)
509         return 0;
510 
511     /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
512      * targets, since the payload format will be different */
513     mbi->nFormat = 1;
514     mbi->nDataSize = src->data_size;
515     memcpy(&mbi->data, &src->data, src->data_size);
516 
517     return mbi->nDataSize + sizeof(*mbi);
518 }
519 
handle_extradata(void * buffer,int index)520 bool venc_dev::handle_extradata(void *buffer, int index)
521 {
522     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
523     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
524 
525     if (!extradata_info.uaddr) {
526         DEBUG_PRINT_ERROR("Extradata buffers not allocated");
527         return false;
528     }
529 
530     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
531                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
532 
533     if (extradata_info.buffer_size >
534             p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
535         DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
536         p_extra = NULL;
537         return false;
538     } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
539         /* A lot of the code below assumes this condition, so error out if it's not met */
540         DEBUG_PRINT_ERROR("Extradata ABI mismatch");
541         return false;
542     }
543 
544     struct msm_vidc_extradata_header *p_extradata = NULL;
545     do {
546         p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
547             ((char *)p_extradata) + p_extradata->size :
548             extradata_info.uaddr + index * extradata_info.buffer_size);
549 
550         switch (p_extradata->type) {
551             case MSM_VIDC_EXTRADATA_METADATA_MBI:
552             {
553                 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
554                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
555                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
556                 p_extra->nPortIndex = OMX_DirOutput;
557                 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
558                 p_extra->nDataSize = payloadSize;
559                 break;
560             }
561             case MSM_VIDC_EXTRADATA_METADATA_LTR:
562             {
563                 *p_extra->data = *p_extradata->data;
564                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
565                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
566                 p_extra->nPortIndex = OMX_DirOutput;
567                 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
568                 p_extra->nDataSize = p_extradata->data_size;
569                 break;
570             }
571             case MSM_VIDC_EXTRADATA_NONE:
572                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
573                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
574                 p_extra->nPortIndex = OMX_DirOutput;
575                 p_extra->eType = OMX_ExtraDataNone;
576                 p_extra->nDataSize = 0;
577                 break;
578             default:
579                 /* No idea what this stuff is, just skip over it */
580                 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
581                         p_extradata->type);
582                 continue;
583         }
584 
585         p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
586     } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
587 
588     /* Just for debugging: Traverse the list of extra datas  and spit it out onto log */
589     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
590                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
591     while(p_extra->eType != OMX_ExtraDataNone)
592     {
593         DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
594                 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
595                 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
596 
597         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
598                 p_extra->nSize);
599     }
600 
601     return true;
602 }
603 
venc_set_format(int format)604 int venc_dev::venc_set_format(int format)
605 {
606     int rc = true;
607 
608     if (format)
609         color_format = format;
610     else {
611         color_format = 0;
612         rc = false;
613     }
614 
615     return rc;
616 }
617 
allocate_extradata()618 OMX_ERRORTYPE venc_dev::allocate_extradata()
619 {
620     if (extradata_info.allocated) {
621         DEBUG_PRINT_ERROR("Extradata already allocated!");
622         return OMX_ErrorNone;
623     }
624 
625 #ifdef USE_ION
626 
627     if (extradata_info.buffer_size) {
628         if (extradata_info.ion.ion_alloc_data.handle) {
629             munmap((void *)extradata_info.uaddr, extradata_info.size);
630             close(extradata_info.ion.fd_ion_data.fd);
631             venc_handle->free_ion_memory(&extradata_info.ion);
632         }
633 
634         extradata_info.size = ALIGN(extradata_info.size, SZ_4K);
635 
636         extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory(
637                 extradata_info.size,
638                 &extradata_info.ion.ion_alloc_data,
639                 &extradata_info.ion.fd_ion_data, 0);
640 
641         if (extradata_info.ion.ion_device_fd < 0) {
642             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
643             return OMX_ErrorInsufficientResources;
644         }
645 
646         extradata_info.uaddr = (char *)mmap(NULL,
647                 extradata_info.size,
648                 PROT_READ|PROT_WRITE, MAP_SHARED,
649                 extradata_info.ion.fd_ion_data.fd , 0);
650 
651         if (extradata_info.uaddr == MAP_FAILED) {
652             DEBUG_PRINT_ERROR("Failed to map extradata memory");
653             close(extradata_info.ion.fd_ion_data.fd);
654             venc_handle->free_ion_memory(&extradata_info.ion);
655             return OMX_ErrorInsufficientResources;
656         }
657     }
658 
659 #endif
660     extradata_info.allocated = 1;
661     return OMX_ErrorNone;
662 }
663 
free_extradata()664 void venc_dev::free_extradata()
665 {
666 #ifdef USE_ION
667 
668     if (extradata_info.uaddr) {
669         munmap((void *)extradata_info.uaddr, extradata_info.size);
670         close(extradata_info.ion.fd_ion_data.fd);
671         venc_handle->free_ion_memory(&extradata_info.ion);
672     }
673 
674     memset(&extradata_info, 0, sizeof(extradata_info));
675 #endif
676 }
677 
venc_get_output_log_flag()678 bool venc_dev::venc_get_output_log_flag()
679 {
680     return (m_debug.out_buffer_log == 1);
681 }
682 
venc_output_log_buffers(const char * buffer_addr,int buffer_len)683 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
684 {
685     if (venc_handle->is_secure_session()) {
686         DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
687         return -1;
688     }
689 
690     if (!m_debug.outfile) {
691         int size = 0;
692         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
693            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
694                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
695         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
696            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
697                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
698         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
699            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
700                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
701         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
702            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
703                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
704         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
705            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
706                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
707         }
708         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
709              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
710                                 m_debug.outfile_name, size);
711         }
712         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
713         if (!m_debug.outfile) {
714             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
715                                m_debug.outfile_name, errno);
716             m_debug.outfile_name[0] = '\0';
717             return -1;
718         }
719     }
720     if (m_debug.outfile && buffer_len) {
721         DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
722         fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
723     }
724     return 0;
725 }
726 
venc_extradata_log_buffers(char * buffer_addr)727 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
728 {
729     if (!m_debug.extradatafile && m_debug.extradata_log) {
730         int size = 0;
731         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
732            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
733                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
734         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
735            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
736                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
737         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
738            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
739                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
740         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
741            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
742                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
743         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
744            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
745                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
746         }
747         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
748              DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
749                                 m_debug.extradatafile_name, size);
750         }
751 
752         m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
753         if (!m_debug.extradatafile) {
754             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
755                                m_debug.extradatafile_name, errno);
756             m_debug.extradatafile_name[0] = '\0';
757             return -1;
758         }
759     }
760 
761     if (m_debug.extradatafile) {
762         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
763         do {
764             p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
765                     ((char *)p_extra) + p_extra->nSize);
766             fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
767         } while (p_extra->eType != OMX_ExtraDataNone);
768     }
769     return 0;
770 }
771 
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset)772 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) {
773     if (venc_handle->is_secure_session()) {
774         DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
775         return -1;
776     }
777 
778     if (!m_debug.infile) {
779         int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
780                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
781         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
782              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
783                                 m_debug.infile_name, size);
784         }
785         m_debug.infile = fopen (m_debug.infile_name, "ab");
786         if (!m_debug.infile) {
787             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
788             m_debug.infile_name[0] = '\0';
789             return -1;
790         }
791     }
792     if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
793         unsigned long i, msize;
794         int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
795         int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
796         unsigned char *pvirt,*ptemp;
797 
798         char *temp = (char *)pbuffer->pBuffer;
799 
800         msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
801         if (metadatamode == 1) {
802             pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
803             if (pvirt) {
804                ptemp = pvirt;
805                for (i = 0; i < m_sVenc_cfg.input_height; i++) {
806                     fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
807                     ptemp += stride;
808                }
809                ptemp = pvirt + (stride * scanlines);
810                for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
811                    fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
812                    ptemp += stride;
813                }
814                munmap(pvirt, msize);
815              } else if (pvirt == MAP_FAILED) {
816                  DEBUG_PRINT_ERROR("%s mmap failed", __func__);
817                  return -1;
818              }
819         } else {
820             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
821                  fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
822                  temp += stride;
823             }
824 
825             temp = (char *)pbuffer->pBuffer + (stride * scanlines);
826 
827             for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
828                 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
829                 temp += stride;
830             }
831         }
832     }
833     return 0;
834 }
835 
venc_open(OMX_U32 codec)836 bool venc_dev::venc_open(OMX_U32 codec)
837 {
838     int r;
839     unsigned int alignment = 0,buffer_size = 0, temp =0;
840     struct v4l2_control control;
841     OMX_STRING device_name = (OMX_STRING)"/dev/video33";
842     char property_value[PROPERTY_VALUE_MAX] = {0};
843     char platform_name[PROPERTY_VALUE_MAX] = {0};
844 
845     property_get("ro.board.platform", platform_name, "0");
846     property_get("vidc.enc.narrow.searchrange", property_value, "0");
847     enable_mv_narrow_searchrange = atoi(property_value);
848 
849     if (!strncmp(platform_name, "msm8610", 7)) {
850         device_name = (OMX_STRING)"/dev/video/q6_enc";
851         supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
852     }
853     m_nDriver_fd = open (device_name, O_RDWR);
854 
855     if (m_nDriver_fd == 0) {
856         DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
857         m_nDriver_fd = open (device_name, O_RDWR);
858     }
859 
860     if ((int)m_nDriver_fd < 0) {
861         DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
862         return false;
863     }
864 
865     DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
866     // set the basic configuration of the video encoder driver
867     m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
868     m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
869     m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
870     m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
871     m_sVenc_cfg.fps_num = 30;
872     m_sVenc_cfg.fps_den = 1;
873     m_sVenc_cfg.targetbitrate = 64000;
874     m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
875     m_codec = codec;
876 
877     if (codec == OMX_VIDEO_CodingMPEG4) {
878         m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
879         codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
880         profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
881         session_qp_range.minqp = 1;
882         session_qp_range.maxqp = 31;
883     } else if (codec == OMX_VIDEO_CodingH263) {
884         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
885         codec_profile.profile = VEN_PROFILE_H263_BASELINE;
886         profile_level.level = VEN_LEVEL_H263_20;
887         session_qp_range.minqp = 1;
888         session_qp_range.maxqp = 31;
889     } else if (codec == OMX_VIDEO_CodingAVC) {
890         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
891         codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
892         profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
893         session_qp_range.minqp = 1;
894         session_qp_range.maxqp = 51;
895     } else if (codec == OMX_VIDEO_CodingVP8) {
896         m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
897         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
898         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
899         session_qp_range.minqp = 1;
900         session_qp_range.maxqp = 128;
901     } else if (codec == OMX_VIDEO_CodingHEVC) {
902         m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
903         session_qp_range.minqp = 1;
904         session_qp_range.maxqp = 51;
905         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
906         profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
907     }
908     session_qp_values.minqp = session_qp_range.minqp;
909     session_qp_values.maxqp = session_qp_range.maxqp;
910 
911     int ret;
912     ret = subscribe_to_events(m_nDriver_fd);
913 
914     if (ret) {
915         DEBUG_PRINT_ERROR("Subscribe Event Failed");
916         return false;
917     }
918 
919     struct v4l2_capability cap;
920 
921     struct v4l2_fmtdesc fdesc;
922 
923     struct v4l2_format fmt;
924 
925     struct v4l2_requestbuffers bufreq;
926 
927     ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
928 
929     if (ret) {
930         DEBUG_PRINT_ERROR("Failed to query capabilities");
931     } else {
932         DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
933                 " version = %d, capabilities = %x", cap.driver, cap.card,
934                 cap.bus_info, cap.version, cap.capabilities);
935     }
936 
937     ret=0;
938     fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
939     fdesc.index=0;
940 
941     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
942         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
943                 fdesc.pixelformat, fdesc.flags);
944         fdesc.index++;
945     }
946 
947     fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
948     fdesc.index=0;
949 
950     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
951         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
952                 fdesc.pixelformat, fdesc.flags);
953         fdesc.index++;
954     }
955 
956     if (venc_handle->is_secure_session()) {
957         m_sOutput_buff_property.alignment = SZ_1M;
958         m_sInput_buff_property.alignment  = SZ_1M;
959     } else {
960         m_sOutput_buff_property.alignment = SZ_4K;
961         m_sInput_buff_property.alignment  = SZ_4K;
962     }
963     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
964     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
965     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
966     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
967 
968     /*TODO: Return values not handled properly in this function anywhere.
969      * Need to handle those.*/
970     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
971 
972     if (ret) {
973         DEBUG_PRINT_ERROR("Failed to set format on capture port");
974         return false;
975     }
976 
977     m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
978 
979     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
980     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
981     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
982     fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
983     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
984 
985     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
986     m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
987 
988     bufreq.memory = V4L2_MEMORY_USERPTR;
989     bufreq.count = 2;
990 
991     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
992     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
993     m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
994 
995     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
996     bufreq.count = 2;
997     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
998     m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
999 
1000     if(venc_handle->is_secure_session()) {
1001         control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1002         control.value = 1;
1003         DEBUG_PRINT_HIGH("ioctl: open secure device");
1004         ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
1005         if (ret) {
1006             DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
1007             return false;
1008         }
1009     }
1010 
1011     resume_in_stopped = 0;
1012     metadatamode = 0;
1013     camera_mode_enabled = false;
1014 
1015     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
1016     control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
1017 
1018     DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
1019 
1020     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1021         DEBUG_PRINT_ERROR("Failed to set control");
1022 
1023     struct v4l2_frmsizeenum frmsize;
1024 
1025     //Get the hardware capabilities
1026     memset((void *)&frmsize,0,sizeof(frmsize));
1027     frmsize.index = 0;
1028     frmsize.pixel_format = m_sVenc_cfg.codectype;
1029     ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1030 
1031     if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1032         DEBUG_PRINT_ERROR("Failed to get framesizes");
1033         return false;
1034     }
1035 
1036     if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1037         capability.min_width = frmsize.stepwise.min_width;
1038         capability.max_width = frmsize.stepwise.max_width;
1039         capability.min_height = frmsize.stepwise.min_height;
1040         capability.max_height = frmsize.stepwise.max_height;
1041     }
1042     //Initialize non-default parameters
1043     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1044         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
1045         control.value = 0x7fffffff;
1046         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1047             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
1048     }
1049 
1050     property_get("vidc.debug.turbo", property_value, "0");
1051     if (atoi(property_value)) {
1052         DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
1053         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
1054         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
1055         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1056             DEBUG_PRINT_ERROR("Failed to set turbo mode");
1057         }
1058     }
1059 
1060     sess_priority.priority = 1; /* default to non-real-time */
1061     if (venc_set_session_priority(sess_priority.priority)) {
1062         DEBUG_PRINT_ERROR("Setting session priority failed");
1063         return OMX_ErrorUnsupportedSetting;
1064     }
1065     return true;
1066 }
1067 
1068 
unsubscribe_to_events(int fd)1069 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
1070 {
1071     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1072     struct v4l2_event_subscription sub;
1073     int array_sz = sizeof(event_type)/sizeof(int);
1074     int i,rc;
1075 
1076     if (fd < 0) {
1077        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1078         return OMX_ErrorBadParameter;
1079     }
1080 
1081     for (i = 0; i < array_sz; ++i) {
1082         memset(&sub, 0, sizeof(sub));
1083         sub.type = event_type[i];
1084         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1085 
1086         if (rc) {
1087            DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1088             break;
1089         }
1090     }
1091 
1092     return eRet;
1093 }
1094 
venc_close()1095 void venc_dev::venc_close()
1096 {
1097     struct v4l2_encoder_cmd enc;
1098     DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
1099 
1100     if ((int)m_nDriver_fd >= 0) {
1101         enc.cmd = V4L2_ENC_CMD_STOP;
1102         ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
1103         DEBUG_PRINT_HIGH("venc_close E");
1104 
1105         if (async_thread_created)
1106             pthread_join(m_tid,NULL);
1107 
1108         DEBUG_PRINT_HIGH("venc_close X");
1109         unsubscribe_to_events(m_nDriver_fd);
1110         close(m_nDriver_fd);
1111         m_nDriver_fd = -1;
1112     }
1113 
1114     if (m_debug.infile) {
1115         fclose(m_debug.infile);
1116         m_debug.infile = NULL;
1117     }
1118 
1119     if (m_debug.outfile) {
1120         fclose(m_debug.outfile);
1121         m_debug.outfile = NULL;
1122     }
1123 
1124     if (m_debug.extradatafile) {
1125         fclose(m_debug.extradatafile);
1126         m_debug.extradatafile = NULL;
1127     }
1128 }
1129 
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1130 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1131         OMX_U32 *actual_buff_count,
1132         OMX_U32 *buff_size,
1133         OMX_U32 port)
1134 {
1135     (void)min_buff_count, (void)buff_size;
1136     unsigned long temp_count = 0;
1137 
1138     if (port == 0) {
1139         if (*actual_buff_count > m_sInput_buff_property.mincount) {
1140             temp_count = m_sInput_buff_property.actualcount;
1141             m_sInput_buff_property.actualcount = *actual_buff_count;
1142             DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1143         }
1144     } else {
1145         if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1146             temp_count = m_sOutput_buff_property.actualcount;
1147             m_sOutput_buff_property.actualcount = *actual_buff_count;
1148             DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1149         }
1150     }
1151 
1152     return true;
1153 
1154 }
1155 
venc_loaded_start()1156 bool venc_dev::venc_loaded_start()
1157 {
1158     return true;
1159 }
1160 
venc_loaded_stop()1161 bool venc_dev::venc_loaded_stop()
1162 {
1163     return true;
1164 }
1165 
venc_loaded_start_done()1166 bool venc_dev::venc_loaded_start_done()
1167 {
1168     return true;
1169 }
1170 
venc_loaded_stop_done()1171 bool venc_dev::venc_loaded_stop_done()
1172 {
1173     return true;
1174 }
1175 
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)1176 bool venc_dev::venc_get_seq_hdr(void *buffer,
1177         unsigned buffer_size, unsigned *header_len)
1178 {
1179     (void) buffer, (void) buffer_size, (void) header_len;
1180     return true;
1181 }
1182 
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1183 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1184         OMX_U32 *actual_buff_count,
1185         OMX_U32 *buff_size,
1186         OMX_U32 port)
1187 {
1188     struct v4l2_format fmt;
1189     struct v4l2_requestbuffers bufreq;
1190     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1191     int ret;
1192 
1193     if (port == 0) {
1194         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1195         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1196         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1197         fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1198         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
1199         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1200         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1201         bufreq.memory = V4L2_MEMORY_USERPTR;
1202 
1203         if (*actual_buff_count)
1204             bufreq.count = *actual_buff_count;
1205         else
1206             bufreq.count = 2;
1207 
1208         // Increase buffer-header count for metadata-mode on input port
1209         // to improve buffering and reduce bottlenecks in clients
1210         if (metadatamode && (bufreq.count < 9)) {
1211             DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
1212                 bufreq.count);
1213             bufreq.count = 9;
1214         }
1215         if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
1216             DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
1217             bufreq.count = 11;
1218         } else {
1219             bufreq.count = 12;
1220         }
1221 
1222         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1223         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1224 
1225         if (ret) {
1226             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1227             return false;
1228         }
1229 
1230         m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1231         *min_buff_count = m_sInput_buff_property.mincount;
1232         *actual_buff_count = m_sInput_buff_property.actualcount;
1233 #ifdef USE_ION
1234         // For ION memory allocations of the allocated buffer size
1235         // must be 4k aligned, hence aligning the input buffer
1236         // size to 4k.
1237         m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1238 #endif
1239         *buff_size = m_sInput_buff_property.datasize;
1240     } else {
1241         unsigned int extra_idx = 0;
1242         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1243         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1244         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1245         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1246 
1247         ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1248         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1249         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1250         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1251         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1252         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1253 
1254         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1255         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1256         bufreq.memory = V4L2_MEMORY_USERPTR;
1257 
1258         if (*actual_buff_count)
1259             bufreq.count = *actual_buff_count;
1260         else
1261             bufreq.count = 2;
1262 
1263         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1264         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1265 
1266         if (ret) {
1267             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1268             return false;
1269         }
1270 
1271         m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1272         *min_buff_count = m_sOutput_buff_property.mincount;
1273         *actual_buff_count = m_sOutput_buff_property.actualcount;
1274         *buff_size = m_sOutput_buff_property.datasize;
1275         num_planes = fmt.fmt.pix_mp.num_planes;
1276         extra_idx = EXTRADATA_IDX(num_planes);
1277 
1278         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1279             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1280         } else if (extra_idx >= VIDEO_MAX_PLANES) {
1281             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1282             return OMX_ErrorBadParameter;
1283         }
1284 
1285         extradata_info.buffer_size = extra_data_size;
1286         extradata_info.count = m_sOutput_buff_property.actualcount;
1287         extradata_info.size = extradata_info.buffer_size * extradata_info.count;
1288     }
1289 
1290     return true;
1291 }
1292 
venc_set_param(void * paramData,OMX_INDEXTYPE index)1293 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
1294 {
1295     DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1296     struct v4l2_format fmt;
1297     struct v4l2_requestbuffers bufreq;
1298     int ret;
1299 
1300     switch ((int)index) {
1301         case OMX_IndexParamPortDefinition:
1302             {
1303                 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1304                 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1305                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1306 
1307                 if (portDefn->nPortIndex == PORT_INDEX_IN) {
1308                     if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1309                         return false;
1310                     }
1311 
1312                     if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1313                         return false;
1314                     }
1315                     if (enable_mv_narrow_searchrange &&
1316                         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1317                         (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1318                         if (venc_set_searchrange() == false) {
1319                             DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1320                         }
1321                     }
1322                     if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1323                             m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1324                         DEBUG_PRINT_LOW("Basic parameter has changed");
1325                         m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1326                         m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1327                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1328                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1329                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1330                         fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1331                         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
1332 
1333                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1334                             DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1335                             hw_overload = errno == EBUSY;
1336                             return false;
1337                         }
1338 
1339                         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1340                         bufreq.memory = V4L2_MEMORY_USERPTR;
1341                         bufreq.count = portDefn->nBufferCountActual;
1342                         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1343 
1344                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1345                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1346                             return false;
1347                         }
1348 
1349                         if (bufreq.count == portDefn->nBufferCountActual)
1350                             m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1351 
1352                         if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1353                             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1354                     }
1355 
1356                     DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1357                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1358                     if (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >= 3840 * 2160) {
1359                         if (venc_set_perf_mode(V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) == false) {
1360                             DEBUG_PRINT_ERROR("ERROR: Failed to set Power save mode");
1361                         }
1362                     }
1363                 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1364                     m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1365                     m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1366                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1367                     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1368                     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1369                     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1370 
1371                     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1372                         DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1373                         hw_overload = errno == EBUSY;
1374                         return false;
1375                     }
1376 
1377                     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1378 
1379                     if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1380                         return false;
1381                     }
1382 
1383                         m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1384                         bufreq.memory = V4L2_MEMORY_USERPTR;
1385                         bufreq.count = portDefn->nBufferCountActual;
1386                         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1387 
1388                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1389                             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1390                                     (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1391                             return false;
1392                         }
1393 
1394                         if (bufreq.count == portDefn->nBufferCountActual)
1395                             m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1396 
1397                         if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1398                             m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1399 
1400                         if (num_planes > 1)
1401                             extradata_info.count = m_sOutput_buff_property.actualcount;
1402 
1403                     DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1404                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1405                 } else {
1406                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1407                 }
1408 
1409                 break;
1410             }
1411         case OMX_IndexParamVideoPortFormat:
1412             {
1413                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1414                 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1415                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1416 
1417                 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1418                     if (!venc_set_color_format(portFmt->eColorFormat)) {
1419                         return false;
1420                     }
1421                 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1422                     if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1423                         return false;
1424                     }
1425                 } else {
1426                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1427                 }
1428 
1429                 break;
1430             }
1431         case OMX_IndexParamVideoBitrate:
1432             {
1433                 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1434                 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1435                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1436 
1437                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1438                     if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1439                         DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1440                         return false;
1441                     }
1442 
1443                     if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1444                         DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1445                         return false;
1446                     }
1447                 } else {
1448                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1449                 }
1450 
1451                 break;
1452             }
1453         case OMX_IndexParamVideoMpeg4:
1454             {
1455                 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1456                 OMX_U32 bFrames = 0;
1457 
1458                 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1459                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1460 
1461                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1462                     if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1463                         DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1464                         return false;
1465                     }
1466 
1467                     m_profile_set = false;
1468                     m_level_set = false;
1469 
1470                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1471                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1472                         return false;
1473                     } else {
1474                         if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1475                             if (pParam->nBFrames) {
1476                                 bFrames = pParam->nBFrames;
1477                             }
1478                         } else {
1479                             if (pParam->nBFrames) {
1480                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1481                                 bFrames = 0;
1482                             }
1483                         }
1484                     }
1485 
1486                     if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
1487                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1488                         return false;
1489                     }
1490 
1491                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1492                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1493                         return false;
1494                     }
1495                 } else {
1496                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1497                 }
1498 
1499                 break;
1500             }
1501         case OMX_IndexParamVideoH263:
1502             {
1503                 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1504                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1505                 OMX_U32 bFrames = 0;
1506 
1507                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1508                     m_profile_set = false;
1509                     m_level_set = false;
1510 
1511                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1512                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1513                         return false;
1514                     }
1515 
1516                     if (pParam->nBFrames)
1517                         DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1518 
1519                     if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
1520                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1521                         return false;
1522                     }
1523                 } else {
1524                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1525                 }
1526 
1527                 break;
1528             }
1529         case OMX_IndexParamVideoAvc:
1530             {
1531                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1532                 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1533                 OMX_U32 bFrames = 0;
1534 
1535                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1536                     DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1537                             pParam->eProfile,pParam->eLevel);
1538 
1539                     m_profile_set = false;
1540                     m_level_set = false;
1541 
1542                     if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1543                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1544                                 pParam->eProfile, pParam->eLevel);
1545                         return false;
1546                     } else {
1547                         if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1548                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) OMX_VIDEO_AVCProfileConstrainedBaseline) &&
1549                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1550                             if (pParam->nBFrames) {
1551                                 bFrames = pParam->nBFrames;
1552                             }
1553                         } else {
1554                             if (pParam->nBFrames) {
1555                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1556                                 bFrames = 0;
1557                             }
1558                         }
1559                     }
1560 
1561                     if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
1562                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1563                         return false;
1564                     }
1565 
1566                     if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1567                         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1568                         return false;
1569                     }
1570 
1571                     if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1572                         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1573                         return false;
1574                     }
1575 
1576                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1577                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1578                         return false;
1579                     }
1580                 } else {
1581                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1582                 }
1583 
1584                 //TBD, lot of other variables to be updated, yet to decide
1585                 break;
1586             }
1587         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1588             {
1589                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1590                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1591                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1592                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1593                                         pParam->eProfile, pParam->eLevel);
1594                     return false;
1595                 }
1596                 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1597                     DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1598                     return false;
1599                  }
1600                 if(!venc_set_ltrmode(1, 1)) {
1601                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1602                    return false;
1603                 }
1604 
1605                  // For VP8, hier-p and ltr are mutually exclusive features in firmware
1606                  // Disable hier-p if ltr is enabled.
1607                  if (m_codec == OMX_VIDEO_CodingVP8) {
1608                      DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1609                      if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1610                         DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1611                      }
1612                  }
1613 
1614                 break;
1615             }
1616             case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1617             {
1618                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1619                 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1620                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1621                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1622                                         pParam->eProfile, pParam->eLevel);
1623                     return false;
1624                 }
1625                 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1626                     DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1627 
1628                 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1629                 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1630                 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1631                     DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1632                     return false;
1633                 }
1634                 break;
1635             }
1636         case OMX_IndexParamVideoIntraRefresh:
1637             {
1638                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1639                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1640                     (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1641 
1642                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1643                     if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1644                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1645                         return false;
1646                     }
1647                 } else {
1648                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1649                 }
1650 
1651                 break;
1652             }
1653         case OMX_IndexParamVideoErrorCorrection:
1654             {
1655                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1656                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1657                     (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1658 
1659                 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1660                     if (venc_set_error_resilience(error_resilience) == false) {
1661                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1662                         return false;
1663                     }
1664                 } else {
1665                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1666                 }
1667 
1668                 break;
1669             }
1670         case OMX_IndexParamVideoProfileLevelCurrent:
1671             {
1672                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1673                 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1674                     (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1675 
1676                 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1677                     m_profile_set = false;
1678                     m_level_set = false;
1679 
1680                     if (!venc_set_profile_level (profile_level->eProfile,
1681                                 profile_level->eLevel)) {
1682                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1683                         return false;
1684                     }
1685                 } else {
1686                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1687                 }
1688 
1689                 break;
1690             }
1691         case OMX_IndexParamVideoQuantization:
1692             {
1693                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
1694                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1695                     (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1696                 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1697                     if (venc_set_session_qp (session_qp->nQpI,
1698                                 session_qp->nQpP,
1699                                 session_qp->nQpB) == false) {
1700                         DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
1701                         return false;
1702                     }
1703                 } else {
1704                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1705                 }
1706 
1707                 break;
1708             }
1709         case QOMX_IndexParamVideoInitialQp:
1710             {
1711                 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
1712                     (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
1713                  if (initqp->bEnableInitQp) {
1714                     DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
1715                     if(venc_enable_initial_qp(initqp) == false) {
1716                        DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
1717                        return OMX_ErrorUnsupportedSetting;
1718                      }
1719                  } else
1720                     DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
1721                 break;
1722             }
1723         case OMX_QcomIndexParamVideoQPRange:
1724             {
1725                 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
1726                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
1727                     (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
1728 
1729                 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1730                     if(venc_set_session_qp_range (session_qp_range->minQP,
1731                                 session_qp_range->maxQP) == false) {
1732                         DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
1733                             (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
1734                         return false;
1735                     } else {
1736                         session_qp_values.minqp = session_qp_range->minQP;
1737                         session_qp_values.maxqp = session_qp_range->maxQP;
1738                     }
1739                 } else {
1740                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1741                 }
1742 
1743                 break;
1744             }
1745         case OMX_QcomIndexEnableSliceDeliveryMode:
1746             {
1747                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1748                     (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1749 
1750                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1751                     if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1752                         DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1753                         return OMX_ErrorUnsupportedSetting;
1754                     }
1755                 } else {
1756                     DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1757                             "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
1758                     return OMX_ErrorBadPortIndex;
1759                 }
1760 
1761                 break;
1762             }
1763         case OMX_ExtraDataVideoEncoderSliceInfo:
1764             {
1765                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1766                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1767 
1768                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
1769                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
1770                     return false;
1771                 }
1772 
1773                 extradata = true;
1774                 break;
1775             }
1776         case OMX_ExtraDataVideoEncoderMBInfo:
1777             {
1778                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
1779                 OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
1780 
1781                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
1782                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
1783                     return false;
1784                 }
1785 
1786                 extradata = true;
1787                 break;
1788             }
1789         case OMX_QcomIndexParamSequenceHeaderWithIDR:
1790             {
1791                 PrependSPSPPSToIDRFramesParams * pParam =
1792                     (PrependSPSPPSToIDRFramesParams *)paramData;
1793 
1794                 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
1795                 if(venc_set_inband_video_header(pParam->bEnable) == false) {
1796                     DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
1797                     return OMX_ErrorUnsupportedSetting;
1798                 }
1799 
1800                 break;
1801             }
1802         case OMX_QcomIndexParamH264AUDelimiter:
1803             {
1804                 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
1805                     (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
1806 
1807                 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
1808                 if(venc_set_au_delimiter(pParam->bEnable) == false) {
1809                     DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
1810                     return OMX_ErrorUnsupportedSetting;
1811                 }
1812 
1813                 break;
1814             }
1815          case OMX_QcomIndexHierarchicalStructure:
1816            {
1817                QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
1818                    (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
1819 
1820                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1821                     if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
1822                         DEBUG_PRINT_ERROR("Setting Hier P count failed");
1823                         return false;
1824                     }
1825                 } else {
1826                     DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
1827                     return false;
1828                 }
1829 
1830                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1831                 // Disable ltr if hier-p is enabled.
1832                 if (m_codec == OMX_VIDEO_CodingVP8) {
1833                     DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
1834                     if(!venc_set_ltrmode(0, 1)) {
1835                          DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
1836                      }
1837                 }
1838                 break;
1839            }
1840         case OMX_QcomIndexParamPerfLevel:
1841             {
1842                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
1843                         (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
1844                 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
1845                 if(!venc_set_perf_level(pParam->ePerfLevel)) {
1846                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
1847                     return false;
1848                 } else {
1849                     performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
1850                 }
1851                 break;
1852             }
1853         case OMX_QcomIndexParamH264VUITimingInfo:
1854             {
1855                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1856                         (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1857                 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1858                 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1859                     DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1860                     return false;
1861                 } else {
1862                     vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1863                 }
1864                 break;
1865             }
1866         case OMX_QcomIndexParamPeakBitrate:
1867             {
1868                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
1869                         (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
1870                 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
1871                 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
1872                     DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
1873                     return false;
1874                 } else {
1875                     peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
1876                 }
1877                 break;
1878             }
1879        case OMX_QcomIndexParamSetMVSearchrange:
1880             {
1881                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
1882                is_searchrange_set = true;
1883                if (!venc_set_searchrange()) {
1884                    DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1885                    return false;
1886                }
1887             }
1888             break;
1889         case OMX_QcomIndexParamVideoLTRCount:
1890             {
1891                 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
1892                 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1893                         (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1894                 if (pParam->nCount > 0) {
1895                     if (venc_set_ltrmode(1, pParam->nCount) == false) {
1896                         DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
1897                         return false;
1898                     }
1899                 } else {
1900                     if (venc_set_ltrmode(0, 0) == false) {
1901                         DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
1902                         return false;
1903                     }
1904                 }
1905                 break;
1906             }
1907         case OMX_QcomIndexParamVideoHybridHierpMode:
1908             {
1909                 QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* pParam =
1910                     (QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData;
1911 
1912                 if (!venc_set_hybrid_hierp(pParam->nHpLayers)) {
1913                      DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
1914                      return OMX_ErrorUnsupportedSetting;
1915                 }
1916                 break;
1917             }
1918         case OMX_IndexParamAndroidVideoTemporalLayering:
1919             {
1920                 if (venc_set_temporal_layers(
1921                         (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
1922                     DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
1923                     return false;
1924                 }
1925                 break;
1926             }
1927         case OMX_IndexParamVideoSliceFMO:
1928         default:
1929             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1930                     index);
1931             break;
1932             //case
1933     }
1934 
1935     return true;
1936 }
1937 
venc_set_config(void * configData,OMX_INDEXTYPE index)1938 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1939 {
1940 
1941     DEBUG_PRINT_LOW("Inside venc_set_config");
1942 
1943     switch ((int)index) {
1944         case OMX_IndexConfigVideoBitrate:
1945             {
1946                 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1947                     configData;
1948                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
1949 
1950                 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1951                     if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1952                         DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
1953                         return false;
1954                     }
1955                 } else {
1956                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1957                 }
1958 
1959                 break;
1960             }
1961         case OMX_IndexConfigVideoFramerate:
1962             {
1963                 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1964                     configData;
1965                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
1966 
1967                 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1968                     if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1969                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1970                         return false;
1971                     }
1972                 } else {
1973                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1974                 }
1975 
1976                 break;
1977             }
1978         case QOMX_IndexConfigVideoIntraperiod:
1979             {
1980                 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
1981                 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1982                     (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1983 
1984                 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1985                     if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1986                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1987                         return false;
1988                     }
1989                 }
1990 
1991                 break;
1992             }
1993         case OMX_IndexConfigVideoIntraVOPRefresh:
1994             {
1995                 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1996                     configData;
1997                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1998 
1999                 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2000                     if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2001                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2002                         return false;
2003                     }
2004                 } else {
2005                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2006                 }
2007 
2008                 break;
2009             }
2010         case OMX_IndexConfigCommonRotate:
2011             {
2012                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2013                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2014                 OMX_U32 nFrameWidth;
2015                 if (!config_rotation) {
2016                    return false;
2017                 }
2018                 if (true == deinterlace_enabled) {
2019                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2020                     return false;
2021                 }
2022                 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2023                 nFrameWidth = m_sVenc_cfg.dvs_width;
2024                 m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
2025                 m_sVenc_cfg.dvs_height = nFrameWidth;
2026 
2027                 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2028                     DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2029                     return false;
2030                 }
2031 
2032                 break;
2033             }
2034         case OMX_IndexConfigVideoAVCIntraPeriod:
2035             {
2036                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2037                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2038 
2039                 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2040                         == false) {
2041                     DEBUG_PRINT_ERROR("ERROR: Setting "
2042                             "OMX_IndexConfigVideoAVCIntraPeriod failed");
2043                     return false;
2044                 }
2045                 break;
2046             }
2047         case OMX_IndexConfigCommonDeinterlace:
2048             {
2049                 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2050                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2051                 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2052                     if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2053                         m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2054                     {
2055                         DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2056                         return false;
2057                     }
2058                     if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2059                         DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2060                         return false;
2061                     }
2062                 } else {
2063                 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2064                 }
2065                 break;
2066             }
2067        case OMX_IndexConfigVideoVp8ReferenceFrame:
2068            {
2069                OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2070                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2071                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2072                     (vp8refframe->bUseGoldenFrame)) {
2073                     if(venc_set_useltr(0x1) == false) {
2074                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2075                         return false;
2076                     }
2077                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2078                     (vp8refframe->bGoldenFrameRefresh)) {
2079                     if(venc_set_markltr(0x1) == false) {
2080                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2081                         return false;
2082                     }
2083                 } else {
2084                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2085                 }
2086                 break;
2087             }
2088         case OMX_QcomIndexConfigVideoLTRUse:
2089             {
2090                 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2091                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2092                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2093                     if (venc_set_useltr(pParam->nID) == false) {
2094                         DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2095                         return false;
2096                     }
2097                 } else {
2098                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2099                 }
2100                 break;
2101             }
2102         case OMX_QcomIndexConfigVideoLTRMark:
2103             {
2104                 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2105                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2106                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2107                     if (venc_set_markltr(pParam->nID) == false) {
2108                         DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2109                         return false;
2110                     }
2111                 }  else {
2112                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2113                 }
2114                 break;
2115             }
2116         case OMX_QcomIndexConfigPerfLevel:
2117             {
2118                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2119                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2120                 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2121                 if (!venc_set_perf_level(perf->ePerfLevel)) {
2122                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2123                     return false;
2124                 } else {
2125                     performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2126                 }
2127                 break;
2128             }
2129         case OMX_QcomIndexConfigVideoVencPerfMode:
2130             {
2131                 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2132                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2133                 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2134                     DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2135                     return false;
2136                 }
2137                 break;
2138             }
2139         case OMX_IndexConfigPriority:
2140             {
2141                 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2142                 DEBUG_PRINT_LOW("Set_config: priority %u",priority->nU32);
2143                 if (!venc_set_session_priority(priority->nU32)) {
2144                     DEBUG_PRINT_ERROR("Failed to set priority");
2145                     return false;
2146                 }
2147                 break;
2148             }
2149         case OMX_IndexConfigOperatingRate:
2150             {
2151                 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2152                 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2153                 if (!venc_set_operatingrate(rate->nU32)) {
2154                     DEBUG_PRINT_ERROR("Failed to set operating rate");
2155                     return false;
2156                 }
2157                 break;
2158             }
2159        case OMX_IndexConfigAndroidIntraRefresh:
2160             {
2161                 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2162                 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2163 
2164                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2165                     OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2166                     OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2167 
2168                     if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2169                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2170                         return false;
2171                     }
2172                 } else {
2173                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2174                 }
2175                 break;
2176             }
2177         case OMX_IndexParamAndroidVideoTemporalLayering:
2178             {
2179                 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2180                 return false;
2181             }
2182         default:
2183             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2184             break;
2185     }
2186 
2187     return true;
2188 }
2189 
venc_stop(void)2190 unsigned venc_dev::venc_stop( void)
2191 {
2192     struct venc_msg venc_msg;
2193     struct v4l2_requestbuffers bufreq;
2194     int rc = 0, ret = 0;
2195 
2196     if (!stopped) {
2197         enum v4l2_buf_type cap_type;
2198 
2199         if (streaming[OUTPUT_PORT]) {
2200             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2201             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2202 
2203             if (rc) {
2204                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2205                         cap_type, rc);
2206             } else
2207                 streaming[OUTPUT_PORT] = false;
2208 
2209             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2210             bufreq.memory = V4L2_MEMORY_USERPTR;
2211             bufreq.count = 0;
2212             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2213             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2214 
2215             if (ret) {
2216                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2217                 return false;
2218             }
2219         }
2220 
2221         if (!rc && streaming[CAPTURE_PORT]) {
2222             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2223             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2224 
2225             if (rc) {
2226                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2227                         cap_type, rc);
2228             } else
2229                 streaming[CAPTURE_PORT] = false;
2230 
2231             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2232             bufreq.memory = V4L2_MEMORY_USERPTR;
2233             bufreq.count = 0;
2234             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2235             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2236 
2237             if (ret) {
2238                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2239                 return false;
2240             }
2241         }
2242 
2243         if (!rc && !ret) {
2244             venc_stop_done();
2245             stopped = 1;
2246             /*set flag to re-configure when started again*/
2247             resume_in_stopped = 1;
2248 
2249         }
2250     }
2251 
2252     return rc;
2253 }
2254 
venc_pause(void)2255 unsigned venc_dev::venc_pause(void)
2256 {
2257     pthread_mutex_lock(&pause_resume_mlock);
2258     paused = true;
2259     pthread_mutex_unlock(&pause_resume_mlock);
2260     return 0;
2261 }
2262 
venc_resume(void)2263 unsigned venc_dev::venc_resume(void)
2264 {
2265     pthread_mutex_lock(&pause_resume_mlock);
2266     paused = false;
2267     pthread_mutex_unlock(&pause_resume_mlock);
2268 
2269     return pthread_cond_signal(&pause_resume_cond);
2270 }
2271 
venc_start_done(void)2272 unsigned venc_dev::venc_start_done(void)
2273 {
2274     struct venc_msg venc_msg;
2275     venc_msg.msgcode = VEN_MSG_START;
2276     venc_msg.statuscode = VEN_S_SUCCESS;
2277     venc_handle->async_message_process(venc_handle,&venc_msg);
2278     return 0;
2279 }
2280 
venc_stop_done(void)2281 unsigned venc_dev::venc_stop_done(void)
2282 {
2283     struct venc_msg venc_msg;
2284     free_extradata();
2285     venc_msg.msgcode=VEN_MSG_STOP;
2286     venc_msg.statuscode=VEN_S_SUCCESS;
2287     venc_handle->async_message_process(venc_handle,&venc_msg);
2288     return 0;
2289 }
2290 
venc_set_message_thread_id(pthread_t tid)2291 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2292 {
2293     async_thread_created = true;
2294     m_tid=tid;
2295     return 0;
2296 }
2297 
2298 
venc_start(void)2299 unsigned venc_dev::venc_start(void)
2300 {
2301     enum v4l2_buf_type buf_type;
2302     int ret, r;
2303     struct v4l2_control control;
2304 
2305     memset(&control, 0, sizeof(control));
2306 
2307     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2308             __func__);
2309     m_level_set = false;
2310 
2311     if (!venc_set_profile_level(0, 0)) {
2312         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2313                 __func__);
2314     } else {
2315         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2316                 __func__, codec_profile.profile, profile_level.level);
2317     }
2318 
2319     // re-configure the temporal layers as RC-mode and key-frame interval
2320     // might have changed since the client last configured the layers.
2321     if (temporal_layers_config.nPLayers) {
2322         if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2323             DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2324         } else {
2325             // request buffers on capture port again since internal (scratch)-
2326             // buffer requirements may change (i.e if we switch from non-hybrid
2327             // to hybrid mode and vice-versa)
2328             struct v4l2_requestbuffers bufreq;
2329 
2330             bufreq.memory = V4L2_MEMORY_USERPTR;
2331             bufreq.count = m_sOutput_buff_property.actualcount;
2332             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2333             if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2334                 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2335             }
2336         }
2337     }
2338 
2339     venc_config_print();
2340 
2341     if(resume_in_stopped){
2342         /*set buffercount when restarted*/
2343         venc_reconfig_reqbufs();
2344         resume_in_stopped = 0;
2345     }
2346 
2347     /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
2348     if (slice_mode.enable && multislice.mslice_size &&
2349             (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
2350         DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
2351                 (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
2352                 MAX_SUPPORTED_SLICES_PER_FRAME);
2353         return 1;
2354     }
2355 
2356     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2357     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2358     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
2359 
2360     if (ret)
2361         return 1;
2362 
2363     streaming[CAPTURE_PORT] = true;
2364 
2365     control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
2366     control.value = 1;
2367     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2368     if (ret) {
2369         DEBUG_PRINT_ERROR("failed to request seq header");
2370         return 1;
2371     }
2372 
2373     stopped = 0;
2374     return 0;
2375 }
2376 
hiermode_string(int val)2377 inline const char* hiermode_string(int val)
2378 {
2379     switch(val)
2380     {
2381     case HIER_NONE:
2382         return "No Hier";
2383     case HIER_P:
2384         return "Hier-P";
2385     case HIER_B:
2386         return "Hier-B";
2387     case HIER_P_HYBRID:
2388         return "Hybrid Hier-P";
2389     default:
2390         return "No hier";
2391     }
2392 }
2393 
venc_config_print()2394 void venc_dev::venc_config_print()
2395 {
2396 
2397     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
2398             m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
2399 
2400     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
2401             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
2402             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2403 
2404     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
2405             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
2406             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2407 
2408     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
2409             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
2410 
2411     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
2412             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
2413 
2414     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2415             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2416 
2417     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
2418             session_qp_values.minqp, session_qp_values.maxqp);
2419 
2420     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
2421             voptimecfg.voptime_resolution, multislice.mslice_mode,
2422             multislice.mslice_size);
2423 
2424     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
2425             entropy.longentropysel, entropy.cabacmodel);
2426 
2427     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
2428             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
2429             dbkfilter.slicebeta_offset);
2430 
2431     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
2432             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
2433 
2434     DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
2435             ltrinfo.enabled, ltrinfo.count);
2436 
2437     if (hier_layers.numlayers) {
2438         DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
2439                 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
2440     }
2441 
2442     if (temporal_layers_config.nPLayers) {
2443         DEBUG_PRINT_INFO("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %u",
2444                 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
2445                 intra_period.num_pframes + intra_period.num_bframes + 1);
2446     }
2447 
2448     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
2449 
2450     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
2451 
2452     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
2453 
2454     DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
2455 
2456     DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
2457 }
2458 
venc_reconfig_reqbufs()2459 bool venc_dev::venc_reconfig_reqbufs()
2460 {
2461     struct v4l2_requestbuffers bufreq;
2462 
2463     bufreq.memory = V4L2_MEMORY_USERPTR;
2464     bufreq.count = m_sInput_buff_property.actualcount;
2465     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2466     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2467             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
2468             return false;
2469     }
2470 
2471     bufreq.memory = V4L2_MEMORY_USERPTR;
2472     bufreq.count = m_sOutput_buff_property.actualcount;
2473     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2474     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
2475     {
2476             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
2477             return false;
2478     }
2479     return true;
2480 }
2481 
venc_flush(unsigned port)2482 unsigned venc_dev::venc_flush( unsigned port)
2483 {
2484     struct v4l2_encoder_cmd enc;
2485     DEBUG_PRINT_LOW("in %s", __func__);
2486 
2487     enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
2488     enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
2489 
2490     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
2491         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
2492         return -1;
2493     }
2494 
2495     return 0;
2496 
2497 }
2498 
2499 //allocating I/P memory from pmem and register with the device
2500 
2501 
venc_use_buf(void * buf_addr,unsigned port,unsigned index)2502 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
2503 {
2504 
2505     struct pmem *pmem_tmp;
2506     struct v4l2_buffer buf;
2507     struct v4l2_plane plane[VIDEO_MAX_PLANES];
2508     int rc = 0;
2509     unsigned int extra_idx;
2510 
2511     pmem_tmp = (struct pmem *)buf_addr;
2512     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
2513 
2514     if (port == PORT_INDEX_IN) {
2515         buf.index = index;
2516         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2517         buf.memory = V4L2_MEMORY_USERPTR;
2518         plane[0].length = pmem_tmp->size;
2519         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2520         plane[0].reserved[0] = pmem_tmp->fd;
2521         plane[0].reserved[1] = 0;
2522         plane[0].data_offset = pmem_tmp->offset;
2523         buf.m.planes = plane;
2524         buf.length = 1;
2525 
2526         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2527 
2528         if (rc)
2529             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2530     } else if (port == PORT_INDEX_OUT) {
2531         extra_idx = EXTRADATA_IDX(num_planes);
2532 
2533         if ((num_planes > 1) && (extra_idx)) {
2534             rc = allocate_extradata();
2535 
2536             if (rc)
2537                 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc);
2538         }
2539 
2540         buf.index = index;
2541         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2542         buf.memory = V4L2_MEMORY_USERPTR;
2543         plane[0].length = pmem_tmp->size;
2544         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2545         plane[0].reserved[0] = pmem_tmp->fd;
2546         plane[0].reserved[1] = 0;
2547         plane[0].data_offset = pmem_tmp->offset;
2548         buf.m.planes = plane;
2549         buf.length = num_planes;
2550 
2551         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2552             plane[extra_idx].length = extradata_info.buffer_size;
2553             plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2554 #ifdef USE_ION
2555             plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2556 #endif
2557             plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2558             plane[extra_idx].data_offset = 0;
2559         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
2560             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
2561             return OMX_ErrorBadParameter;
2562         }
2563 
2564         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2565 
2566         if (rc)
2567             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2568     } else {
2569         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
2570         return false;
2571     }
2572 
2573     return true;
2574 }
2575 
venc_free_buf(void * buf_addr,unsigned port)2576 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
2577 {
2578     struct pmem *pmem_tmp;
2579     struct venc_bufferpayload dev_buffer;
2580 
2581     memset(&dev_buffer, 0, sizeof(dev_buffer));
2582     pmem_tmp = (struct pmem *)buf_addr;
2583 
2584     if (port == PORT_INDEX_IN) {
2585         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2586         dev_buffer.fd  = pmem_tmp->fd;
2587         dev_buffer.maped_size = pmem_tmp->size;
2588         dev_buffer.sz = pmem_tmp->size;
2589         dev_buffer.offset = pmem_tmp->offset;
2590         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2591                 dev_buffer.pbuffer, \
2592                 dev_buffer.fd, \
2593                 dev_buffer.offset, \
2594                 dev_buffer.maped_size);
2595 
2596     } else if (port == PORT_INDEX_OUT) {
2597         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2598         dev_buffer.fd  = pmem_tmp->fd;
2599         dev_buffer.sz = pmem_tmp->size;
2600         dev_buffer.maped_size = pmem_tmp->size;
2601         dev_buffer.offset = pmem_tmp->offset;
2602 
2603         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2604                 dev_buffer.pbuffer, \
2605                 dev_buffer.fd, \
2606                 dev_buffer.offset, \
2607                 dev_buffer.maped_size);
2608     } else {
2609         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
2610         return false;
2611     }
2612 
2613     return true;
2614 }
2615 
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2616 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
2617         OMX_U32 width, OMX_U32 height)
2618 {
2619     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2620             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2621             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2622             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2623             src_chroma_offset = width * height;
2624 
2625     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2626         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2627         //Do chroma first, so that we can convert it in-place
2628         src_buf += width * height;
2629         dst_buf += y_stride * y_scanlines;
2630         for (int line = height / 2 - 1; line >= 0; --line) {
2631             memmove(dst_buf + line * uv_stride,
2632                     src_buf + line * width,
2633                     width);
2634         }
2635 
2636         dst_buf = src_buf = buffer->pBuffer;
2637         //Copy the Y next
2638         for (int line = height - 1; line > 0; --line) {
2639             memmove(dst_buf + line * y_stride,
2640                     src_buf + line * width,
2641                     width);
2642         }
2643     } else {
2644         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
2645                 Insufficient bufferLen=%u v/s Required=%u",
2646                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
2647                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
2648         return false;
2649     }
2650 
2651     return true;
2652 }
2653 
venc_get_performance_level(OMX_U32 * perflevel)2654 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
2655 {
2656     if (!perflevel) {
2657         DEBUG_PRINT_ERROR("Null pointer error");
2658         return false;
2659     } else {
2660         *perflevel = performance_level.perflevel;
2661         return true;
2662     }
2663 }
2664 
venc_get_vui_timing_info(OMX_U32 * enabled)2665 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
2666 {
2667     if (!enabled) {
2668         DEBUG_PRINT_ERROR("Null pointer error");
2669         return false;
2670     } else {
2671         *enabled = vui_timing_info.enabled;
2672         return true;
2673     }
2674 }
2675 
venc_get_peak_bitrate(OMX_U32 * peakbitrate)2676 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
2677 {
2678     if (!peakbitrate) {
2679         DEBUG_PRINT_ERROR("Null pointer error");
2680         return false;
2681     } else {
2682         *peakbitrate = peak_bitrate.peakbitrate;
2683         return true;
2684     }
2685 }
2686 
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2687 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
2688 {
2689     struct pmem *temp_buffer;
2690     struct v4l2_buffer buf;
2691     struct v4l2_plane plane;
2692     int rc=0;
2693     struct OMX_BUFFERHEADERTYPE *bufhdr;
2694     struct v4l2_control control;
2695     encoder_media_buffer_type * meta_buf = NULL;
2696     temp_buffer = (struct pmem *)buffer;
2697 
2698     memset (&buf, 0, sizeof(buf));
2699     memset (&plane, 0, sizeof(plane));
2700 
2701     if (buffer == NULL) {
2702         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
2703         return false;
2704     }
2705 
2706     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2707 
2708     DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
2709 
2710     if (pmem_data_buf) {
2711         DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
2712         plane.m.userptr = (unsigned long)pmem_data_buf;
2713         plane.data_offset = bufhdr->nOffset;
2714         plane.length = bufhdr->nAllocLen;
2715         plane.bytesused = bufhdr->nFilledLen;
2716     } else {
2717         // --------------------------------------------------------------------------------------
2718         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
2719         // ---------------------------------------------------------------------------------------
2720         // Camera-2              1            CameraSource   0              meta-handle
2721         // Camera-3              1            GrallocSource  0              gralloc-private-handle
2722         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
2723         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
2724         // ---------------------------------------------------------------------------------------
2725         if (metadatamode) {
2726             plane.m.userptr = index;
2727             meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
2728 
2729             if (!meta_buf) {
2730                 //empty EOS buffer
2731                 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
2732                     plane.data_offset = bufhdr->nOffset;
2733                     plane.length = bufhdr->nAllocLen;
2734                     plane.bytesused = bufhdr->nFilledLen;
2735                     DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
2736                 } else {
2737                     return false;
2738                 }
2739             } else if (!color_format) {
2740 		int color_space = 0;
2741 
2742                 if ((meta_buf->buffer_type == kMetadataBufferTypeCameraSource) ||
2743                         (meta_buf->buffer_type == kMetadataBufferTypeNativeHandleSource)) {
2744                     if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 3 &&
2745                         meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709) {
2746                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2747 			color_space = V4L2_COLORSPACE_REC709;
2748 		    }
2749 
2750                     if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 2) {
2751                     plane.data_offset = meta_buf->meta_handle->data[1];
2752                     plane.length = meta_buf->meta_handle->data[2];
2753                     plane.bytesused = meta_buf->meta_handle->data[2];
2754                     }
2755                     if (!camera_mode_enabled) {
2756                         camera_mode_enabled = true;
2757                         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
2758                         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
2759                         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2760                         if (rc)
2761                             DEBUG_PRINT_HIGH("Failed to set control for perf level");
2762                         DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, meta_buf type = %d",
2763                                 control.id, control.value, meta_buf->buffer_type);
2764                     }
2765                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
2766                             fd, plane.bytesused, plane.length, buf.flags);
2767                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
2768                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
2769                     fd = handle->fd;
2770                     plane.data_offset = 0;
2771                     plane.length = handle->size;
2772                     plane.bytesused = handle->size;
2773                     if ((!camera_mode_enabled) && (handle->flags & private_handle_t:: PRIV_FLAGS_CAMERA_WRITE)) {
2774                         camera_mode_enabled = true;
2775                         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
2776                         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
2777                         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2778                         if (rc)
2779                             DEBUG_PRINT_HIGH("Failed to set perl level");
2780                         DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, flags = 0x%x",
2781                                 control.id, control.value, handle->flags);
2782                     }
2783 
2784                     if (handle->base_metadata) {
2785                         MetaData_t *pMeta =
2786                                 reinterpret_cast<MetaData_t*>(handle->base_metadata);
2787                         ColorSpace_t csc = pMeta->operation & UPDATE_COLOR_SPACE ?
2788                                 pMeta->colorSpace : (ColorSpace_t)-1;
2789                         if (csc == ITU_R_709) {
2790                             buf.flags |= V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2791                             DEBUG_PRINT_LOW("venc_empty_buf: force 601 -> 709 clamping");
2792 			    color_space = V4L2_COLORSPACE_REC709;
2793                         } else if (csc == ITU_R_601_FR) {
2794                             DEBUG_PRINT_LOW("venc_empty_buf: 601 full-range");
2795                             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
2796                         } else if (csc == ITU_R_601) {
2797                             DEBUG_PRINT_LOW("venc_empty_buf: 601 clamped");
2798                             color_space = V4L2_COLORSPACE_BT878;
2799                         }
2800                     } else {
2801                         DEBUG_PRINT_LOW("venc_empty_buf: gralloc metadata is NULL");
2802                     }
2803                         DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
2804                                 ": filled %d of %d", fd, plane.bytesused, plane.length);
2805                 }
2806 
2807 
2808 		if (!streaming[OUTPUT_PORT]) {
2809 			struct v4l2_format fmt;
2810 			fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2811 			fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
2812 			fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space);
2813 			fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
2814 			fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
2815 			if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
2816 				DEBUG_PRINT_ERROR("Failed setting color format in in etb %x", m_sVenc_cfg.inputformat);
2817 				return false;
2818 			}
2819 		}
2820             } else {
2821                 plane.data_offset = bufhdr->nOffset;
2822                 plane.length = bufhdr->nAllocLen;
2823                 plane.bytesused = bufhdr->nFilledLen;
2824                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
2825                         ": filled %d of %d", fd, plane.bytesused, plane.length);
2826             }
2827         } else {
2828             plane.data_offset = bufhdr->nOffset;
2829             plane.length = bufhdr->nAllocLen;
2830             plane.bytesused = bufhdr->nFilledLen;
2831             DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
2832                     fd, plane.bytesused, plane.length);
2833         }
2834     }
2835 
2836     buf.index = index;
2837     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2838     buf.memory = V4L2_MEMORY_USERPTR;
2839     plane.reserved[0] = fd;
2840     plane.reserved[1] = 0;
2841     buf.m.planes = &plane;
2842     buf.length = 1;
2843 
2844     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2845         buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
2846 
2847     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
2848     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
2849     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2850 
2851     if (rc) {
2852         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
2853         return false;
2854     }
2855 
2856     etb++;
2857 
2858     if (!streaming[OUTPUT_PORT]) {
2859         enum v4l2_buf_type buf_type;
2860         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2861         int ret;
2862         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
2863 
2864         if (ret) {
2865             DEBUG_PRINT_ERROR("Failed to call streamon");
2866             if (errno == EBUSY) {
2867                 hw_overload = true;
2868             }
2869             return false;
2870         } else {
2871             streaming[OUTPUT_PORT] = true;
2872         }
2873     }
2874     if (m_debug.in_buffer_log) {
2875         venc_input_log_buffers(bufhdr, fd, plane.data_offset);
2876     }
2877 
2878     return true;
2879 }
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2880 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
2881 {
2882     struct pmem *temp_buffer = NULL;
2883     struct venc_buffer  frameinfo;
2884     struct v4l2_buffer buf;
2885     struct v4l2_plane plane[VIDEO_MAX_PLANES];
2886     int rc = 0;
2887     unsigned int extra_idx;
2888     struct OMX_BUFFERHEADERTYPE *bufhdr;
2889 
2890     if (buffer == NULL)
2891         return false;
2892 
2893     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2894 
2895     if (pmem_data_buf) {
2896         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
2897         plane[0].m.userptr = (unsigned long)pmem_data_buf;
2898     } else {
2899         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
2900         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
2901     }
2902 
2903     buf.index = index;
2904     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2905     buf.memory = V4L2_MEMORY_USERPTR;
2906     plane[0].length = bufhdr->nAllocLen;
2907     plane[0].bytesused = bufhdr->nFilledLen;
2908     plane[0].reserved[0] = fd;
2909     plane[0].reserved[1] = 0;
2910     plane[0].data_offset = bufhdr->nOffset;
2911     buf.m.planes = plane;
2912     buf.length = num_planes;
2913 
2914     extra_idx = EXTRADATA_IDX(num_planes);
2915 
2916     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2917         plane[extra_idx].bytesused = 0;
2918         plane[extra_idx].length = extradata_info.buffer_size;
2919         plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2920 #ifdef USE_ION
2921         plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2922 #endif
2923         plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2924         plane[extra_idx].data_offset = 0;
2925     } else if (extra_idx >= VIDEO_MAX_PLANES) {
2926         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
2927         return false;
2928     }
2929 
2930     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2931 
2932     if (rc) {
2933         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
2934         return false;
2935     }
2936 
2937     ftb++;
2938     return true;
2939 }
2940 
venc_set_inband_video_header(OMX_BOOL enable)2941 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
2942 {
2943     struct v4l2_control control;
2944 
2945     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
2946     if(enable) {
2947         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
2948     } else {
2949         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
2950     }
2951 
2952     DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
2953     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2954         DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
2955         return false;
2956     }
2957     return true;
2958 }
2959 
venc_set_au_delimiter(OMX_BOOL enable)2960 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
2961 {
2962     struct v4l2_control control;
2963 
2964     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
2965     if(enable) {
2966         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
2967     } else {
2968         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
2969     }
2970 
2971     DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
2972     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2973         DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
2974         return false;
2975     }
2976     return true;
2977 }
2978 
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)2979 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
2980 {
2981     // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
2982     if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
2983         return false;
2984 
2985     // Check for bframes with Hier-P-Hybrid
2986     if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
2987         return false;
2988 
2989     // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
2990     if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
2991            hier_layers.hier_mode == HIER_B || ltrinfo.count))
2992         return false;
2993 
2994     // Check for LTR with Hier-P-Hybrid
2995     if (count && hier_layers.hier_mode == HIER_P_HYBRID)
2996         return false;
2997 
2998     return true;
2999 }
3000 
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)3001 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
3002                                     OMX_U32 num_layers)
3003 {
3004     struct v4l2_control control;
3005 
3006     if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
3007         DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
3008         return false;
3009     }
3010 
3011     if (type == QOMX_HIERARCHICALCODING_P) {
3012         // Reduce layer count by 1 before sending to driver. This avoids
3013         // driver doing the same in multiple places.
3014         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
3015         control.value = num_layers - 1;
3016         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
3017         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3018             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
3019             return false;
3020         }
3021         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3022             DEBUG_PRINT_LOW("Set H264_SVC_NAL");
3023             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
3024             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
3025             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3026                 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
3027                 return false;
3028             }
3029         }
3030         hier_layers.hier_mode = HIER_P;
3031     } else if (type == QOMX_HIERARCHICALCODING_B) {
3032         if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
3033             DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
3034             return false;
3035         }
3036         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
3037         control.value = num_layers - 1;
3038         DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
3039         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3040             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
3041             return false;
3042         }
3043         hier_layers.hier_mode = HIER_B;
3044     } else {
3045         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
3046         return false;
3047     }
3048     hier_layers.numlayers = num_layers;
3049     return true;
3050 }
3051 
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)3052 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
3053 {
3054     struct v4l2_control control;
3055 
3056     DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
3057 
3058     if (enable == OMX_FALSE) {
3059         /* No easy way to turn off extradata to the driver
3060          * at the moment */
3061         return false;
3062     }
3063 
3064     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
3065     switch (extra_data) {
3066         case OMX_ExtraDataVideoEncoderSliceInfo:
3067             control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
3068             break;
3069         case OMX_ExtraDataVideoEncoderMBInfo:
3070             control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
3071             break;
3072         default:
3073             DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
3074             return false;
3075     }
3076 
3077     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3078         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
3079                 (unsigned int)extra_data, errno);
3080         return false;
3081     }
3082 
3083     return true;
3084 }
3085 
venc_set_slice_delivery_mode(OMX_U32 enable)3086 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
3087 {
3088     struct v4l2_control control;
3089 
3090     if (enable) {
3091         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
3092         control.value = 1;
3093         DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
3094 
3095         if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3096             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3097                 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
3098                 return false;
3099             } else {
3100                 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
3101                 slice_mode.enable = 1;
3102             }
3103         } else {
3104             DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
3105                     "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
3106                     m_sVenc_cfg.codectype);
3107         }
3108     } else {
3109         DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
3110     }
3111 
3112     return true;
3113 }
3114 
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)3115 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
3116 {
3117     int rc;
3118     struct v4l2_control control;
3119     struct v4l2_ext_control ctrl[4];
3120     struct v4l2_ext_controls controls;
3121 
3122     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
3123     ctrl[0].value = initqp->nQpI;
3124     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
3125     ctrl[1].value = initqp->nQpP;
3126     ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
3127     ctrl[2].value = initqp->nQpB;
3128     ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
3129     ctrl[3].value = initqp->bEnableInitQp;
3130 
3131     controls.count = 4;
3132     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3133     controls.controls = ctrl;
3134 
3135     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
3136                     controls.controls[0].id, controls.controls[0].value,
3137                     controls.controls[1].id, controls.controls[1].value,
3138                     controls.controls[2].id, controls.controls[2].value,
3139                     controls.controls[3].id, controls.controls[3].value);
3140 
3141     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3142     if (rc) {
3143         DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
3144         return false;
3145     }
3146 
3147     init_qp.iframeqp = initqp->nQpI;
3148     init_qp.pframeqp = initqp->nQpP;
3149     init_qp.bframeqp = initqp->nQpB;
3150     init_qp.enableinitqp = initqp->bEnableInitQp;
3151 
3152     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
3153                     controls.controls[0].id, controls.controls[0].value,
3154                     controls.controls[1].id, controls.controls[1].value,
3155                     controls.controls[2].id, controls.controls[2].value,
3156                     controls.controls[3].id, controls.controls[3].value);
3157     return true;
3158 }
3159 
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)3160 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
3161 {
3162     int rc;
3163     struct v4l2_control control;
3164 
3165     control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
3166     control.value = i_frame_qp;
3167 
3168     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3169     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3170 
3171     if (rc) {
3172         DEBUG_PRINT_ERROR("Failed to set control");
3173         return false;
3174     }
3175 
3176     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3177     session_qp.iframeqp = control.value;
3178 
3179     control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
3180     control.value = p_frame_qp;
3181 
3182     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3183     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3184 
3185     if (rc) {
3186         DEBUG_PRINT_ERROR("Failed to set control");
3187         return false;
3188     }
3189 
3190     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3191 
3192     session_qp.pframeqp = control.value;
3193 
3194     if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
3195             (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3196 
3197         control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
3198         control.value = b_frame_qp;
3199 
3200         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3201         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3202 
3203         if (rc) {
3204             DEBUG_PRINT_ERROR("Failed to set control");
3205             return false;
3206         }
3207 
3208         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3209 
3210         session_qp.bframeqp = control.value;
3211     }
3212 
3213     return true;
3214 }
3215 
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)3216 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
3217 {
3218     int rc;
3219     struct v4l2_control control;
3220 
3221     if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
3222 
3223         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
3224             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
3225         else
3226             control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
3227         control.value = min_qp;
3228 
3229         DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
3230                 control.id, control.value);
3231         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3232         if (rc) {
3233             DEBUG_PRINT_ERROR("Failed to set control");
3234             return false;
3235         }
3236 
3237         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
3238             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
3239         else
3240             control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
3241         control.value = max_qp;
3242 
3243         DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
3244                 control.id, control.value);
3245         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3246         if (rc) {
3247             DEBUG_PRINT_ERROR("Failed to set control");
3248             return false;
3249         }
3250     } else {
3251         DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
3252             (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
3253     }
3254 
3255     return true;
3256 }
3257 
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)3258 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
3259 {
3260     struct venc_profile requested_profile = {0};
3261     struct ven_profilelevel requested_level = {0};
3262     unsigned long mb_per_frame = 0;
3263     DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
3264             (unsigned int)eProfile, (unsigned int)eLevel);
3265     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
3266         ((m_sVenc_cfg.dvs_width + 15) >> 4);
3267 
3268     if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
3269         DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
3270         return true;
3271     }
3272 
3273     DEBUG_PRINT_LOW("Validating Profile/Level from table");
3274 
3275     if (!venc_validate_profile_level(&eProfile, &eLevel)) {
3276         DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
3277         return false;
3278     }
3279 
3280     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3281         DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
3282                 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
3283                 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
3284 
3285         if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
3286             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
3287         } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
3288             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
3289         } else {
3290             DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
3291                     (unsigned int)eProfile);
3292             return false;
3293         }
3294 
3295         DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
3296                 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
3297                 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
3298                 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
3299 
3300         if (mb_per_frame >= 3600) {
3301             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
3302                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3303 
3304             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
3305                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3306         } else {
3307             switch (eLevel) {
3308                 case OMX_VIDEO_MPEG4Level0:
3309                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
3310                     break;
3311                 case OMX_VIDEO_MPEG4Level0b:
3312                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
3313                     break;
3314                 case OMX_VIDEO_MPEG4Level1:
3315                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
3316                     break;
3317                 case OMX_VIDEO_MPEG4Level2:
3318                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
3319                     break;
3320                 case OMX_VIDEO_MPEG4Level3:
3321                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
3322                     break;
3323                 case OMX_VIDEO_MPEG4Level4a:
3324                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
3325                     break;
3326                 case OMX_VIDEO_MPEG4Level5:
3327                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3328                     break;
3329                 default:
3330                     return false;
3331                     // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
3332                     break;
3333             }
3334         }
3335     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3336 
3337         switch (eProfile) {
3338             case OMX_VIDEO_H263ProfileBaseline:
3339                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
3340                 break;
3341             case OMX_VIDEO_H263ProfileH320Coding:
3342                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
3343                 break;
3344             case OMX_VIDEO_H263ProfileBackwardCompatible:
3345                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
3346                 break;
3347             case OMX_VIDEO_H263ProfileISWV2:
3348                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
3349                 break;
3350             case OMX_VIDEO_H263ProfileISWV3:
3351                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
3352                 break;
3353             case OMX_VIDEO_H263ProfileHighCompression:
3354                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
3355                 break;
3356             case OMX_VIDEO_H263ProfileInternet:
3357                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
3358                 break;
3359             case OMX_VIDEO_H263ProfileInterlace:
3360                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
3361                 break;
3362             case OMX_VIDEO_H263ProfileHighLatency:
3363                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
3364                 break;
3365             default:
3366                 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
3367                         requested_profile.profile);
3368                 return false;
3369         }
3370 
3371         //profile level
3372         switch (eLevel) {
3373             case OMX_VIDEO_H263Level10:
3374                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
3375                 break;
3376             case OMX_VIDEO_H263Level20:
3377                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
3378                 break;
3379             case OMX_VIDEO_H263Level30:
3380                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
3381                 break;
3382             case OMX_VIDEO_H263Level40:
3383                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
3384                 break;
3385             case OMX_VIDEO_H263Level45:
3386                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
3387                 break;
3388             case OMX_VIDEO_H263Level50:
3389                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
3390                 break;
3391             case OMX_VIDEO_H263Level60:
3392                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
3393                 break;
3394             case OMX_VIDEO_H263Level70:
3395                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
3396                 break;
3397             default:
3398                 return false;
3399                 break;
3400         }
3401     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3402         if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
3403             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
3404         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
3405                   eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
3406             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
3407         } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
3408             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
3409         } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
3410             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
3411         } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
3412             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
3413         } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
3414             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
3415         } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
3416             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
3417         } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
3418             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
3419         } else {
3420             DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
3421                     requested_profile.profile);
3422             return false;
3423         }
3424 
3425         //profile level
3426         switch (eLevel) {
3427             case OMX_VIDEO_AVCLevel1:
3428                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
3429                 break;
3430             case OMX_VIDEO_AVCLevel1b:
3431                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
3432                 break;
3433             case OMX_VIDEO_AVCLevel11:
3434                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
3435                 break;
3436             case OMX_VIDEO_AVCLevel12:
3437                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
3438                 break;
3439             case OMX_VIDEO_AVCLevel13:
3440                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
3441                 break;
3442             case OMX_VIDEO_AVCLevel2:
3443                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
3444                 break;
3445             case OMX_VIDEO_AVCLevel21:
3446                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
3447                 break;
3448             case OMX_VIDEO_AVCLevel22:
3449                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
3450                 break;
3451             case OMX_VIDEO_AVCLevel3:
3452                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
3453                 break;
3454             case OMX_VIDEO_AVCLevel31:
3455                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
3456                 break;
3457             case OMX_VIDEO_AVCLevel32:
3458                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
3459                 break;
3460             case OMX_VIDEO_AVCLevel4:
3461                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
3462                 break;
3463             case OMX_VIDEO_AVCLevel41:
3464                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
3465                 break;
3466             case OMX_VIDEO_AVCLevel42:
3467                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
3468                 break;
3469             case OMX_VIDEO_AVCLevel5:
3470                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
3471                 break;
3472             case OMX_VIDEO_AVCLevel51:
3473                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
3474                 break;
3475             case OMX_VIDEO_AVCLevel52:
3476                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3477                 break;
3478             case OMX_VIDEO_AVCLevelMax:
3479                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3480                 break;
3481             default :
3482                 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
3483                         requested_level.level);
3484                 return false;
3485                 break;
3486         }
3487     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3488         if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
3489             DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
3490                         (unsigned int)eProfile);
3491             return false;
3492         }
3493         requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
3494         m_profile_set = true;
3495         switch(eLevel) {
3496             case OMX_VIDEO_VP8Level_Version0:
3497                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
3498                 break;
3499             case OMX_VIDEO_VP8Level_Version1:
3500                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
3501                 break;
3502             default:
3503                 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
3504                             (unsigned int)eLevel);
3505                 return false;
3506                 break;
3507         }
3508     }  else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3509         if (eProfile == OMX_VIDEO_HEVCProfileMain) {
3510             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
3511         } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
3512             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
3513         } else {
3514             DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
3515                     requested_profile.profile);
3516             return false;
3517         }
3518 
3519         //profile level
3520         switch (eLevel) {
3521             case OMX_VIDEO_HEVCMainTierLevel1:
3522                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
3523                 break;
3524             case OMX_VIDEO_HEVCHighTierLevel1:
3525                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
3526                 break;
3527             case OMX_VIDEO_HEVCMainTierLevel2:
3528                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
3529                 break;
3530             case OMX_VIDEO_HEVCHighTierLevel2:
3531                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
3532                 break;
3533             case OMX_VIDEO_HEVCMainTierLevel21:
3534                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
3535                 break;
3536             case OMX_VIDEO_HEVCHighTierLevel21:
3537                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
3538                 break;
3539             case OMX_VIDEO_HEVCMainTierLevel3:
3540                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
3541                 break;
3542             case OMX_VIDEO_HEVCHighTierLevel3:
3543                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
3544                 break;
3545             case OMX_VIDEO_HEVCMainTierLevel31:
3546                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
3547                 break;
3548             case OMX_VIDEO_HEVCHighTierLevel31:
3549                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
3550                 break;
3551             case OMX_VIDEO_HEVCMainTierLevel4:
3552                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
3553                 break;
3554             case OMX_VIDEO_HEVCHighTierLevel4:
3555                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
3556                 break;
3557             case OMX_VIDEO_HEVCMainTierLevel41:
3558                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
3559                 break;
3560             case OMX_VIDEO_HEVCHighTierLevel41:
3561                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
3562                 break;
3563             case OMX_VIDEO_HEVCMainTierLevel5:
3564                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
3565                 break;
3566             case OMX_VIDEO_HEVCHighTierLevel5:
3567                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
3568                 break;
3569             case OMX_VIDEO_HEVCMainTierLevel51:
3570                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
3571                 break;
3572             case OMX_VIDEO_HEVCHighTierLevel51:
3573                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
3574                 break;
3575             case OMX_VIDEO_HEVCMainTierLevel52:
3576                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
3577                 break;
3578             case OMX_VIDEO_HEVCHighTierLevel52:
3579                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
3580                 break;
3581             case OMX_VIDEO_HEVCMainTierLevel6:
3582                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
3583                 break;
3584             case OMX_VIDEO_HEVCHighTierLevel6:
3585                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
3586                 break;
3587             case OMX_VIDEO_HEVCMainTierLevel61:
3588                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
3589                 break;
3590             case OMX_VIDEO_HEVCHighTierLevel61:
3591                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
3592                 break;
3593             default :
3594                 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
3595                         requested_level.level);
3596                 return false;
3597         }
3598     }
3599 
3600     if (!m_profile_set) {
3601         int rc;
3602         struct v4l2_control control;
3603 
3604         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3605             control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3606         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3607             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
3608         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3609             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
3610         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3611             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
3612         } else {
3613             DEBUG_PRINT_ERROR("Wrong CODEC");
3614             return false;
3615         }
3616 
3617         control.value = requested_profile.profile;
3618 
3619         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3620         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3621 
3622         if (rc) {
3623             DEBUG_PRINT_ERROR("Failed to set control");
3624             return false;
3625         }
3626 
3627         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3628 
3629         codec_profile.profile = control.value;
3630         m_profile_set = true;
3631     }
3632 
3633     if (!m_level_set) {
3634         int rc;
3635         struct v4l2_control control;
3636 
3637         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3638             control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3639         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3640             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
3641         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3642             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
3643         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3644             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3645         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3646             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
3647         } else {
3648             DEBUG_PRINT_ERROR("Wrong CODEC");
3649             return false;
3650         }
3651 
3652         control.value = requested_level.level;
3653 
3654         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3655         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3656 
3657         if (rc) {
3658             DEBUG_PRINT_ERROR("Failed to set control");
3659             return false;
3660         }
3661 
3662         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3663 
3664         profile_level.level = control.value;
3665         m_level_set = true;
3666     }
3667 
3668     return true;
3669 }
3670 
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)3671 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
3672 {
3673 
3674     struct venc_voptimingcfg vop_timing_cfg;
3675 
3676     DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
3677             (unsigned int)TimeIncRes);
3678 
3679     vop_timing_cfg.voptime_resolution = TimeIncRes;
3680 
3681     voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
3682     return true;
3683 }
3684 
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)3685 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
3686 {
3687 
3688     DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
3689     int rc;
3690     struct v4l2_control control;
3691     int pframe = 0, bframe = 0;
3692 
3693     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
3694             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
3695             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
3696             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
3697             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3698         nBFrames=0;
3699     }
3700 
3701     if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0)) {
3702         DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
3703         return false;
3704     }
3705 
3706     intra_period.num_pframes = nPFrames;
3707     intra_period.num_bframes = nBFrames;
3708 
3709     if (!venc_calibrate_gop())
3710     {
3711         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
3712         return false;
3713     }
3714 
3715     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
3716     control.value = intra_period.num_pframes;
3717     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3718 
3719     if (rc) {
3720         DEBUG_PRINT_ERROR("Failed to set control");
3721         return false;
3722     }
3723 
3724     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3725 
3726     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
3727     control.value = intra_period.num_bframes;
3728     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3729     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3730 
3731     if (rc) {
3732         DEBUG_PRINT_ERROR("Failed to set control");
3733         return false;
3734     }
3735 
3736     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
3737 
3738     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3739         control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3740         control.value = 1;
3741 
3742         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3743 
3744         if (rc) {
3745             DEBUG_PRINT_ERROR("Failed to set control");
3746             return false;
3747         }
3748 
3749         idrperiod.idrperiod = 1;
3750     }
3751 
3752     return true;
3753 }
3754 
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)3755 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
3756 {
3757     int rc = 0;
3758     struct v4l2_control control;
3759     DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
3760             (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
3761 
3762     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
3763         DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
3764         return false;
3765     }
3766 
3767     if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
3768         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
3769         return false;
3770     }
3771 
3772     if (!intra_period.num_bframes)
3773     intra_period.num_pframes = nPFrames;
3774     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3775     control.value = nIDRPeriod;
3776 
3777     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3778 
3779     if (rc) {
3780         DEBUG_PRINT_ERROR("Failed to set control");
3781         return false;
3782     }
3783 
3784     idrperiod.idrperiod = nIDRPeriod;
3785     return true;
3786 }
3787 
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)3788 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
3789 {
3790     int rc = 0;
3791     struct v4l2_control control;
3792 
3793     DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
3794 
3795     if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
3796             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
3797 
3798         control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
3799         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3800 
3801         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3802         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3803 
3804         if (rc) {
3805             DEBUG_PRINT_ERROR("Failed to set control");
3806             return false;
3807         }
3808 
3809         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3810         entropy.longentropysel = control.value;
3811 
3812         if (i_cabac_level == 0) {
3813             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
3814         } else if (i_cabac_level == 1) {
3815             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
3816         } else if (i_cabac_level == 2) {
3817             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
3818         }
3819 
3820         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
3821         //control.value = entropy_cfg.cabacmodel;
3822         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3823         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3824 
3825         if (rc) {
3826             DEBUG_PRINT_ERROR("Failed to set control");
3827             return false;
3828         }
3829 
3830         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3831         entropy.cabacmodel=control.value;
3832     } else if (!enable) {
3833         control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
3834         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3835         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3836         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3837 
3838         if (rc) {
3839             DEBUG_PRINT_ERROR("Failed to set control");
3840             return false;
3841         }
3842 
3843         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3844         entropy.longentropysel=control.value;
3845     } else {
3846         DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
3847         return false;
3848     }
3849 
3850     return true;
3851 }
3852 
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)3853 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
3854 {
3855     int rc;
3856     struct v4l2_control control;
3857     bool status = true;
3858 
3859     if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
3860         control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
3861     } else {
3862         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3863     }
3864 
3865     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3866     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3867     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3868 
3869     if (rc) {
3870         DEBUG_PRINT_ERROR("Failed to set control");
3871         return false;
3872     }
3873 
3874     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3875     multislice.mslice_mode=control.value;
3876 
3877     if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
3878 
3879         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
3880         control.value = nSlicesize;
3881         DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
3882         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3883 
3884         if (rc) {
3885             DEBUG_PRINT_ERROR("Failed to set control");
3886             return false;
3887         }
3888 
3889         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3890         multislice.mslice_size=control.value;
3891 
3892     }
3893 
3894     return status;
3895 }
3896 
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)3897 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
3898 {
3899     bool status = true;
3900     int rc;
3901     struct v4l2_control control_mode,control_mbs;
3902     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
3903 
3904     // There is no disabled mode.  Disabled mode is indicated by a 0 count.
3905     if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
3906         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
3907         return status;
3908     } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
3909             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3910         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
3911         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
3912         control_mbs.value=irMBs;
3913     } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
3914             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3915         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
3916         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3917         control_mbs.value=irMBs;
3918     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
3919             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3920         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
3921     } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
3922             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3923         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
3924         control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3925         control_mbs.value = irMBs;
3926     } else {
3927         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
3928                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
3929         return false;
3930     }
3931 
3932     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
3933     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
3934 
3935     if (rc) {
3936         DEBUG_PRINT_ERROR("Failed to set control");
3937         return false;
3938     }
3939 
3940     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
3941 
3942     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
3943     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
3944 
3945     if (rc) {
3946         DEBUG_PRINT_ERROR("Failed to set control");
3947         return false;
3948     }
3949 
3950     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
3951 
3952     intra_refresh.irmode = control_mode.value;
3953     intra_refresh.mbcount = control_mbs.value;
3954 
3955     return status;
3956 }
3957 
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)3958 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
3959 {
3960     bool status = true;
3961     struct venc_headerextension hec_cfg;
3962     struct venc_multiclicecfg multislice_cfg;
3963     int rc;
3964     OMX_U32 resynchMarkerSpacingBytes = 0;
3965     struct v4l2_control control;
3966 
3967     memset(&control, 0, sizeof(control));
3968 
3969     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3970         if (error_resilience->bEnableHEC) {
3971             hec_cfg.header_extension = 1;
3972         } else {
3973             hec_cfg.header_extension = 0;
3974         }
3975 
3976         hec.header_extension = error_resilience->bEnableHEC;
3977     }
3978 
3979     if (error_resilience->bEnableRVLC) {
3980         DEBUG_PRINT_ERROR("RVLC is not Supported");
3981         return false;
3982     }
3983 
3984     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3985             (error_resilience->bEnableDataPartitioning)) {
3986         DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
3987         return false;
3988     }
3989 
3990     if (error_resilience->nResynchMarkerSpacing) {
3991         resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
3992         resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
3993     }
3994     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3995             (error_resilience->nResynchMarkerSpacing)) {
3996         multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
3997         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3998         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3999         control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
4000     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
4001             error_resilience->bEnableDataPartitioning) {
4002         multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
4003         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
4004         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
4005         control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
4006     } else {
4007         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
4008         multislice_cfg.mslice_size = 0;
4009         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
4010         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
4011     }
4012 
4013     DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
4014             multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
4015     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4016     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4017 
4018     if (rc) {
4019        DEBUG_PRINT_ERROR("Failed to set Slice mode control");
4020         return false;
4021     }
4022 
4023     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4024     multislice.mslice_mode=control.value;
4025 
4026     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
4027     control.value = resynchMarkerSpacingBytes;
4028     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4029 
4030     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4031 
4032     if (rc) {
4033        DEBUG_PRINT_ERROR("Failed to set MAX MB control");
4034         return false;
4035     }
4036 
4037     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4038     multislice.mslice_mode = multislice_cfg.mslice_mode;
4039     multislice.mslice_size = multislice_cfg.mslice_size;
4040     return status;
4041 }
4042 
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)4043 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
4044 {
4045     int rc;
4046     struct v4l2_control control;
4047     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
4048 
4049     if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
4050         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
4051     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
4052         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
4053     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
4054         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
4055     }
4056 
4057     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4058     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4059 
4060     if (rc) {
4061         return false;
4062     }
4063 
4064     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4065 
4066     dbkfilter.db_mode=control.value;
4067 
4068     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
4069     control.value=0;
4070 
4071     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4072     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4073 
4074     if (rc) {
4075         return false;
4076     }
4077 
4078     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4079     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
4080     control.value=0;
4081     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4082     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4083 
4084     if (rc) {
4085         return false;
4086     }
4087 
4088     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4089 
4090 
4091     dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
4092     return true;
4093 }
4094 
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)4095 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
4096 {
4097     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
4098             (unsigned int)nTargetBitrate);
4099     struct v4l2_control control;
4100     int rc = 0;
4101     control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
4102     control.value = nTargetBitrate;
4103 
4104     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4105     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4106 
4107     if (rc) {
4108         DEBUG_PRINT_ERROR("Failed to set control");
4109         return false;
4110     }
4111 
4112     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4113 
4114 
4115     m_sVenc_cfg.targetbitrate = control.value;
4116     bitrate.target_bitrate = control.value;
4117 
4118     if (!config) {
4119         m_level_set = false;
4120 
4121         if (venc_set_profile_level(0, 0)) {
4122             DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
4123         }
4124     }
4125 
4126     return true;
4127 }
4128 
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)4129 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
4130 {
4131     struct v4l2_streamparm parm;
4132     int rc = 0;
4133     struct venc_framerate frame_rate_cfg;
4134     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
4135     parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4136     parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
4137     parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
4138 
4139     if (frame_rate_cfg.fps_numerator > 0)
4140         rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
4141 
4142     if (rc) {
4143         DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
4144         return false;
4145     }
4146 
4147     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
4148     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
4149 
4150     if (!config) {
4151         m_level_set = false;
4152 
4153         if (venc_set_profile_level(0, 0)) {
4154             DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
4155         }
4156     }
4157 
4158     return true;
4159 }
4160 
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)4161 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
4162 {
4163     struct v4l2_format fmt;
4164     int color_space = 0;
4165     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
4166 
4167     if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar ||
4168             (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
4169         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
4170         color_space = V4L2_COLORSPACE_BT878;
4171     } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) {
4172         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
4173         color_space = V4L2_COLORSPACE_BT878;
4174     } else {
4175         DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
4176         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
4177         DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
4178     }
4179 
4180     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4181     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
4182     fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space);
4183     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
4184     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
4185 
4186     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
4187         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
4188         return false;
4189     }
4190 
4191     return true;
4192 }
4193 
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)4194 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
4195 {
4196     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
4197 
4198     if (intra_vop_refresh == OMX_TRUE) {
4199         struct v4l2_control control;
4200         int rc;
4201         control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
4202         control.value = 1;
4203        DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4204         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4205 
4206         if (rc) {
4207            DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
4208             return false;
4209         }
4210 
4211        DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4212     } else {
4213         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
4214     }
4215 
4216     return true;
4217 }
4218 
venc_set_deinterlace(OMX_U32 enable)4219 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
4220 {
4221     DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
4222     struct v4l2_control control;
4223     int rc;
4224     control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
4225     if (enable)
4226         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
4227     else
4228         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
4229 
4230     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4231     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4232     if (rc) {
4233         DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
4234         return false;
4235     }
4236     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4237     deinterlace_enabled = true;
4238     return true;
4239 }
4240 
venc_calibrate_gop()4241 bool venc_dev::venc_calibrate_gop()
4242 {
4243     int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
4244     int num_sub_gops_in_a_gop;
4245     nPframes = intra_period.num_pframes;
4246     nBframes = intra_period.num_bframes;
4247     nLayers = hier_layers.numlayers;
4248 
4249     if (!nPframes) {
4250         DEBUG_PRINT_ERROR("nPframes should be non-zero\n");
4251         return false;
4252     }
4253 
4254     if (nLayers > 1) { /*Multi-layer encoding*/
4255         sub_gop_size = 1 << (nLayers - 1);
4256         /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
4257          * below calculations we are ignoring +1 . Ignoring +1 in below
4258          * calculations is not a mistake but intentional.
4259          */
4260         gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
4261         num_sub_gops_in_a_gop = gop_size/sub_gop_size;
4262         if (nBframes) { /*Hier-B case*/
4263         /*
4264             * Frame Type--> I  B  B  B  P  B  B  B  P  I  B  B  P ...
4265             * Layer -->     0  2  1  2  0  2  1  2  0  0  2  1  2 ...
4266             * nPframes = 2, nBframes = 6, nLayers = 3
4267             *
4268             * Intention is to keep the intraperiod as close as possible to what is desired
4269             * by the client while adjusting nPframes and nBframes to meet other constraints.
4270             * eg1: Input by client: nPframes =  9, nBframes = 14, nLayers = 2
4271             *    Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
4272             *
4273             * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
4274             *    Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
4275             */
4276             nPframes = num_sub_gops_in_a_gop;
4277             nBframes = gop_size - nPframes;
4278         } else { /*Hier-P case*/
4279             /*
4280             * Frame Type--> I  P  P  P  P  P  P  P  I  P  P  P  P ...
4281             * Layer-->      0  2  1  2  0  2  1  2  0  2  1  2  0 ...
4282             * nPframes =  7, nBframes = 0, nLayers = 3
4283             *
4284             * Intention is to keep the intraperiod as close as possible to what is desired
4285             * by the client while adjusting nPframes and nBframes to meet other constraints.
4286             * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
4287             *    Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
4288             *
4289             * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
4290             *     Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
4291             */
4292             nPframes = gop_size - 1;
4293         }
4294     } else { /*Single-layer encoding*/
4295         if (nBframes) {
4296             /* I  P  B  B  B  P  B  B  B   P   B   B   B   I   P   B   B...
4297             *  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17...
4298             * nPframes = 3, nBframes = 9, nLayers = 0
4299             *
4300             * ratio is rounded,
4301             * eg1: nPframes = 9, nBframes = 11 => ratio = 1
4302             * eg2: nPframes = 9, nBframes = 16 => ratio = 2
4303             */
4304             ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
4305             nBframes = ratio * nPframes;
4306         }
4307     }
4308     DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
4309         intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
4310     intra_period.num_pframes = nPframes;
4311     intra_period.num_bframes = nBframes;
4312     hier_layers.numlayers = nLayers;
4313     return true;
4314 }
4315 
venc_set_hybrid_hierp(OMX_U32 layers)4316 bool venc_dev::venc_set_hybrid_hierp(OMX_U32 layers)
4317 {
4318     DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers: %u", layers);
4319     struct v4l2_control control;
4320     int rc;
4321 
4322     if (!venc_validate_hybridhp_params(layers, 0, 0, (int) HIER_P_HYBRID)) {
4323         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4324         return false;
4325     }
4326 
4327     if (!layers || layers > MAX_HYB_HIERP_LAYERS) {
4328         DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", layers);
4329         return false;
4330     }
4331 
4332     hier_layers.numlayers = layers;
4333     hier_layers.hier_mode = HIER_P_HYBRID;
4334     if (venc_calibrate_gop()) {
4335      // Update the driver with the new nPframes and nBframes
4336         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4337         control.value = intra_period.num_pframes;
4338         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4339         if (rc) {
4340             DEBUG_PRINT_ERROR("Failed to set control");
4341             return false;
4342         }
4343 
4344         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4345         control.value = intra_period.num_bframes;
4346         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4347         if (rc) {
4348             DEBUG_PRINT_ERROR("Failed to set control");
4349             return false;
4350         }
4351         DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
4352                          intra_period.num_pframes, intra_period.num_bframes);
4353     } else {
4354         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4355         return false;
4356     }
4357 
4358     control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
4359     control.value = layers - 1;
4360 
4361     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
4362                     control.id, control.value);
4363 
4364     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4365     if (rc) {
4366         DEBUG_PRINT_ERROR("Failed to set hybrid hierp %d", rc);
4367         return false;
4368     }
4369 
4370     DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
4371                     control.id, control.value);
4372     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4373     control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4374     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4375         DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4376         return false;
4377     }
4378     return true;
4379 }
4380 
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)4381 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
4382 {
4383     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
4384     struct v4l2_control control;
4385     struct v4l2_ext_control ctrl[2];
4386     struct v4l2_ext_controls controls;
4387     int rc;
4388 
4389     if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
4390         DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
4391         return false;
4392     }
4393 
4394     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
4395     if (enable)
4396         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
4397     else
4398         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
4399 
4400     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
4401     if (enable && count > 0)
4402         ctrl[1].value = count;
4403     else if (enable)
4404         ctrl[1].value = 1;
4405     else
4406         ctrl[1].value = 0;
4407 
4408     controls.count = 2;
4409     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4410     controls.controls = ctrl;
4411 
4412     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
4413                     controls.controls[0].id, controls.controls[0].value,
4414                     controls.controls[1].id, controls.controls[1].value);
4415 
4416     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4417     if (rc) {
4418         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
4419         return false;
4420     }
4421     ltrinfo.enabled = enable;
4422     ltrinfo.count = count;
4423 
4424     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
4425                     controls.controls[0].id, controls.controls[0].value,
4426                     controls.controls[1].id, controls.controls[1].value);
4427 
4428     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4429     control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR;
4430 
4431     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4432         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
4433         return false;
4434     }
4435 
4436     if (!venc_set_profile_level(0, 0)) {
4437         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
4438                 __func__);
4439     } else {
4440         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
4441                 __func__, codec_profile.profile, profile_level.level);
4442     }
4443 
4444     return true;
4445 }
4446 
venc_set_useltr(OMX_U32 frameIdx)4447 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
4448 {
4449     DEBUG_PRINT_LOW("venc_use_goldenframe");
4450     int rc = true;
4451     struct v4l2_control control;
4452 
4453     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
4454     control.value = frameIdx;
4455 
4456     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4457     if (rc) {
4458         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
4459         return false;
4460     }
4461 
4462     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4463                     control.id, control.value);
4464     return true;
4465 }
4466 
venc_set_markltr(OMX_U32 frameIdx)4467 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
4468 {
4469     DEBUG_PRINT_LOW("venc_set_goldenframe");
4470     int rc = true;
4471     struct v4l2_control control;
4472 
4473     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
4474     control.value = frameIdx;
4475 
4476     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4477     if (rc) {
4478         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
4479         return false;
4480     }
4481 
4482     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4483                     control.id, control.value);
4484     return true;
4485 }
4486 
venc_set_vpe_rotation(OMX_S32 rotation_angle)4487 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
4488 {
4489     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
4490     struct v4l2_control control;
4491     int rc;
4492     struct v4l2_format fmt;
4493     struct v4l2_requestbuffers bufreq;
4494 
4495     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
4496     if (rotation_angle == 0)
4497         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
4498     else if (rotation_angle == 90)
4499         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
4500     else if (rotation_angle == 180)
4501         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
4502     else if (rotation_angle == 270)
4503         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
4504     else {
4505         DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
4506         return false;
4507     }
4508 
4509     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4510     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4511     if (rc) {
4512         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
4513         return false;
4514     }
4515     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4516 
4517     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4518     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
4519     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
4520     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
4521     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
4522         DEBUG_PRINT_ERROR("Failed to set format on capture port");
4523         return false;
4524     }
4525 
4526     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
4527     bufreq.memory = V4L2_MEMORY_USERPTR;
4528     bufreq.count = m_sOutput_buff_property.actualcount;
4529     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4530     if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
4531         DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
4532             return false;
4533     }
4534     if (bufreq.count >= m_sOutput_buff_property.mincount)
4535         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
4536 
4537     return true;
4538 }
4539 
venc_set_searchrange()4540 bool venc_dev::venc_set_searchrange()
4541 {
4542     DEBUG_PRINT_LOW("venc_set_searchrange");
4543     struct v4l2_control control;
4544     struct v4l2_ext_control ctrl[6];
4545     struct v4l2_ext_controls controls;
4546     int rc;
4547 
4548     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4549         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4550         ctrl[0].value = 16;
4551         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4552         ctrl[1].value = 4;
4553         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4554         ctrl[2].value = 16;
4555         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4556         ctrl[3].value = 4;
4557         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4558         ctrl[4].value = 12;
4559         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4560         ctrl[5].value = 4;
4561     } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
4562                (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
4563         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4564         ctrl[0].value = 16;
4565         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4566         ctrl[1].value = 4;
4567         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4568         ctrl[2].value = 16;
4569         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4570         ctrl[3].value = 4;
4571         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4572         ctrl[4].value = 12;
4573         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4574         ctrl[5].value = 4;
4575     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4576         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4577         ctrl[0].value = 4;
4578         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4579         ctrl[1].value = 4;
4580         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4581         ctrl[2].value = 4;
4582         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4583         ctrl[3].value = 4;
4584         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4585         ctrl[4].value = 4;
4586         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4587         ctrl[5].value = 4;
4588     } else {
4589         DEBUG_PRINT_ERROR("Invalid codec type");
4590         return false;
4591     }
4592     controls.count = 6;
4593     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4594     controls.controls = ctrl;
4595 
4596     DEBUG_PRINT_LOW(" Calling IOCTL set control for"
4597         "id=%x, val=%d id=%x, val=%d"
4598         "id=%x, val=%d id=%x, val=%d"
4599         "id=%x, val=%d id=%x, val=%d",
4600         controls.controls[0].id, controls.controls[0].value,
4601         controls.controls[1].id, controls.controls[1].value,
4602         controls.controls[2].id, controls.controls[2].value,
4603         controls.controls[3].id, controls.controls[3].value,
4604         controls.controls[4].id, controls.controls[4].value,
4605         controls.controls[5].id, controls.controls[5].value);
4606 
4607     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4608     if (rc) {
4609         DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
4610         return false;
4611     }
4612     return true;
4613 }
4614 
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)4615 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
4616 {
4617     bool status = true;
4618     struct v4l2_control control;
4619     int rc = 0;
4620     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
4621 
4622     switch (eControlRate) {
4623         case OMX_Video_ControlRateDisable:
4624             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
4625             break;
4626         case OMX_Video_ControlRateVariableSkipFrames:
4627             (supported_rc_modes & RC_VBR_VFR) ?
4628                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
4629                 status = false;
4630             break;
4631         case OMX_Video_ControlRateVariable:
4632             (supported_rc_modes & RC_VBR_CFR) ?
4633                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
4634                 status = false;
4635             break;
4636         case OMX_Video_ControlRateConstantSkipFrames:
4637             (supported_rc_modes & RC_CBR_VFR) ?
4638                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
4639                 status = false;
4640             break;
4641         case OMX_Video_ControlRateConstant:
4642             (supported_rc_modes & RC_CBR_CFR) ?
4643                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
4644                 status = false;
4645             break;
4646         default:
4647             status = false;
4648             break;
4649     }
4650 
4651     if (status) {
4652 
4653         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4654         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4655 
4656         if (rc) {
4657             DEBUG_PRINT_ERROR("Failed to set control");
4658             return false;
4659         }
4660 
4661         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4662 
4663         rate_ctrl.rcmode = control.value;
4664     }
4665 
4666     return status;
4667 }
4668 
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)4669 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
4670 {
4671     bool status = true;
4672     struct v4l2_control control;
4673     int rc = 0;
4674     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
4675 
4676     switch (ePerfLevel) {
4677     case OMX_QCOM_PerfLevelNominal:
4678         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
4679         break;
4680     case OMX_QCOM_PerfLevelTurbo:
4681         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
4682         break;
4683     default:
4684         status = false;
4685         break;
4686     }
4687 
4688     if (status) {
4689         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4690         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4691 
4692         if (rc) {
4693             DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
4694             return false;
4695         }
4696 
4697         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4698     }
4699     return status;
4700 }
4701 
venc_set_perf_mode(OMX_U32 mode)4702 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
4703 {
4704     struct v4l2_control control;
4705     if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
4706         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
4707         control.value = mode;
4708         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
4709         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4710             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
4711             return false;
4712         }
4713         return true;
4714     } else {
4715         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
4716         return false;
4717     }
4718 }
4719 
venc_set_vui_timing_info(OMX_BOOL enable)4720 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
4721 {
4722     struct v4l2_control control;
4723     int rc = 0;
4724     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
4725 
4726     if (enable)
4727         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
4728     else
4729         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
4730 
4731     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4732     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4733     if (rc) {
4734         DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
4735         return false;
4736     }
4737     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4738     return true;
4739 }
4740 
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)4741 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
4742 {
4743     struct v4l2_control control;
4744     int rc = 0;
4745     control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
4746     control.value = nPeakBitrate;
4747 
4748     DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
4749 
4750     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4751     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4752 
4753     if (rc) {
4754         DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
4755         return false;
4756     }
4757 
4758     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4759 
4760     return true;
4761 }
4762 
venc_set_vpx_error_resilience(OMX_BOOL enable)4763 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
4764 {
4765     struct v4l2_control control;
4766     int rc = 0;
4767     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
4768 
4769     if (enable)
4770         control.value = 1;
4771     else
4772         control.value = 0;
4773 
4774     DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
4775 
4776     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4777 
4778     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4779     if (rc) {
4780         DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
4781         return false;
4782     }
4783     vpx_err_resilience.enable = 1;
4784     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4785     return true;
4786 }
4787 
venc_set_session_priority(OMX_U32 priority)4788 bool venc_dev::venc_set_session_priority(OMX_U32 priority) {
4789     struct v4l2_control control;
4790 
4791     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
4792     switch(priority) {
4793         case 0:
4794             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
4795             break;
4796         case 1:
4797             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4798             break;
4799         default:
4800             priority = 1;
4801             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4802             DEBUG_PRINT_ERROR("Unsupported priority level %u", priority);
4803             break;
4804     }
4805 
4806     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4807         DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
4808                 priority == 0 ? "ENABLE" : "DISABLE");
4809         return false;
4810     }
4811 
4812     sess_priority.priority = priority;
4813 
4814     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4815             control.id, control.value);
4816     return true;
4817 }
4818 
venc_set_operatingrate(OMX_U32 rate)4819 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
4820     struct v4l2_control control;
4821 
4822     control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
4823     control.value = rate;
4824 
4825     DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
4826     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4827 
4828     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4829         hw_overload = errno == EBUSY;
4830         DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
4831                 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
4832         return false;
4833     }
4834     operating_rate = rate;
4835     DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  rate >> 16);
4836     return true;
4837 }
4838 
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)4839 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
4840         OMX_U32 *nMaxBLayers) {
4841     temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
4842     temporal_layers_config.nMaxBLayers = 0;
4843 
4844     *nMaxLayers = temporal_layers_config.nMaxLayers;
4845     *nMaxBLayers = temporal_layers_config.nMaxBLayers;
4846     return true;
4847 }
4848 
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)4849 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
4850         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
4851 
4852     if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
4853             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
4854             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
4855         DEBUG_PRINT_ERROR("Temporal layers not supported for %ld", m_sVenc_cfg.codectype);
4856         return OMX_ErrorUnsupportedSetting;
4857     }
4858 
4859     if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
4860             (pTemporalParams->nBLayerCountActual != 0 ||
4861              pTemporalParams->nPLayerCountActual != 1)) {
4862         return OMX_ErrorBadParameter;
4863     } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
4864             pTemporalParams->nPLayerCountActual < 1) {
4865         return OMX_ErrorBadParameter;
4866     }
4867 
4868     if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
4869         DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers (%u) exceeds supported max(%u)",
4870                 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
4871         return OMX_ErrorBadParameter;
4872     } else if (pTemporalParams->nPLayerCountActual >
4873              temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
4874         DEBUG_PRINT_ERROR("TemporalLayer: Requested layers (%u) exceeds supported max(%u)",
4875                 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
4876                 temporal_layers_config.nMaxLayers);
4877         return OMX_ErrorBadParameter;
4878     }
4879 
4880     // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
4881     // use hybrid-HP for best results
4882     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
4883             pTemporalParams->nBLayerCountActual == 0 &&
4884             (rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR)) {
4885         if (!venc_set_hybrid_hierp(pTemporalParams->nPLayerCountActual)) {
4886             DEBUG_PRINT_ERROR("Failed to enable (hybrid) Hier-P with %u layers",
4887                     pTemporalParams->nPLayerCountActual);
4888             return OMX_ErrorUnsupportedSetting;
4889         }
4890         temporal_layers_config.hier_mode = HIER_P_HYBRID;
4891         temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
4892         temporal_layers_config.nBLayers = 0;
4893 
4894         // we ignore layer-size bitrate request for this mode
4895         temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
4896         pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
4897 
4898     } else {
4899         if (pTemporalParams->nBLayerCountActual == 0) {
4900             if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, pTemporalParams->nPLayerCountActual)) {
4901                 DEBUG_PRINT_ERROR("Failed to enable Hier-P with %u layers",
4902                         pTemporalParams->nPLayerCountActual);
4903                 return OMX_ErrorUnsupportedSetting;
4904             }
4905             temporal_layers_config.hier_mode = HIER_P;
4906             temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
4907             temporal_layers_config.nBLayers = 0;
4908 
4909             // TODO: handle layer-wise bitrate request. For now, disregard the setting
4910             temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
4911             pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
4912 
4913         } else {
4914             // we do not support B-frames with enhancement layers for now
4915         }
4916     }
4917 
4918     return OMX_ErrorNone;
4919 }
4920 
venc_set_temporal_layers_internal()4921 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
4922     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
4923     memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
4924 
4925     if (!temporal_layers_config.nPLayers) {
4926         return OMX_ErrorNone;
4927     }
4928     pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4929     pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
4930     pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
4931     pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4932     pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
4933     pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
4934     pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
4935     if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
4936         for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
4937             pTemporalParams.nBitrateRatios[i] =
4938                     temporal_layers_config.nTemporalLayerBitrateRatio[i];
4939         }
4940     }
4941     return venc_set_temporal_layers(&pTemporalParams);
4942 }
4943 
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)4944 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
4945 {
4946     bool status = true;
4947 
4948     if (eProfile == NULL || eLevel == NULL) {
4949         return false;
4950     }
4951 
4952     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4953         switch (codec_profile.profile) {
4954             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4955                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4956                 break;
4957             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4958                 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4959                 break;
4960             default:
4961                 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
4962                 status = false;
4963                 break;
4964         }
4965 
4966         if (!status) {
4967             return status;
4968         }
4969 
4970         //profile level
4971         switch (profile_level.level) {
4972             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
4973                 *eLevel = OMX_VIDEO_MPEG4Level0;
4974                 break;
4975             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
4976                 *eLevel = OMX_VIDEO_MPEG4Level0b;
4977                 break;
4978             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
4979                 *eLevel = OMX_VIDEO_MPEG4Level1;
4980                 break;
4981             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
4982                 *eLevel = OMX_VIDEO_MPEG4Level2;
4983                 break;
4984             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
4985                 *eLevel = OMX_VIDEO_MPEG4Level3;
4986                 break;
4987             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
4988                 *eLevel = OMX_VIDEO_MPEG4Level4;
4989                 break;
4990             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
4991                 *eLevel = OMX_VIDEO_MPEG4Level5;
4992                 break;
4993             default:
4994                 *eLevel = OMX_VIDEO_MPEG4LevelMax;
4995                 status =  false;
4996                 break;
4997         }
4998     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4999         if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
5000             *eProfile = OMX_VIDEO_H263ProfileBaseline;
5001         } else {
5002             *eProfile = OMX_VIDEO_H263ProfileMax;
5003             return false;
5004         }
5005 
5006         switch (profile_level.level) {
5007             case VEN_LEVEL_H263_10:
5008                 *eLevel = OMX_VIDEO_H263Level10;
5009                 break;
5010             case VEN_LEVEL_H263_20:
5011                 *eLevel = OMX_VIDEO_H263Level20;
5012                 break;
5013             case VEN_LEVEL_H263_30:
5014                 *eLevel = OMX_VIDEO_H263Level30;
5015                 break;
5016             case VEN_LEVEL_H263_40:
5017                 *eLevel = OMX_VIDEO_H263Level40;
5018                 break;
5019             case VEN_LEVEL_H263_45:
5020                 *eLevel = OMX_VIDEO_H263Level45;
5021                 break;
5022             case VEN_LEVEL_H263_50:
5023                 *eLevel = OMX_VIDEO_H263Level50;
5024                 break;
5025             case VEN_LEVEL_H263_60:
5026                 *eLevel = OMX_VIDEO_H263Level60;
5027                 break;
5028             case VEN_LEVEL_H263_70:
5029                 *eLevel = OMX_VIDEO_H263Level70;
5030                 break;
5031             default:
5032                 *eLevel = OMX_VIDEO_H263LevelMax;
5033                 status = false;
5034                 break;
5035         }
5036     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5037         switch (codec_profile.profile) {
5038             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
5039                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
5040                 break;
5041             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
5042                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
5043                 break;
5044             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
5045                 *eProfile = OMX_VIDEO_AVCProfileMain;
5046                 break;
5047             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
5048                 *eProfile = OMX_VIDEO_AVCProfileHigh;
5049                 break;
5050             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
5051                 *eProfile = OMX_VIDEO_AVCProfileExtended;
5052                 break;
5053             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
5054                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
5055                 break;
5056             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
5057                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
5058                 break;
5059             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
5060                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
5061                 break;
5062             default:
5063                 *eProfile = OMX_VIDEO_AVCProfileMax;
5064                 status = false;
5065                 break;
5066         }
5067 
5068         if (!status) {
5069             return status;
5070         }
5071 
5072         switch (profile_level.level) {
5073             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
5074                 *eLevel = OMX_VIDEO_AVCLevel1;
5075                 break;
5076             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
5077                 *eLevel = OMX_VIDEO_AVCLevel1b;
5078                 break;
5079             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
5080                 *eLevel = OMX_VIDEO_AVCLevel11;
5081                 break;
5082             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
5083                 *eLevel = OMX_VIDEO_AVCLevel12;
5084                 break;
5085             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
5086                 *eLevel = OMX_VIDEO_AVCLevel13;
5087                 break;
5088             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
5089                 *eLevel = OMX_VIDEO_AVCLevel2;
5090                 break;
5091             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
5092                 *eLevel = OMX_VIDEO_AVCLevel21;
5093                 break;
5094             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
5095                 *eLevel = OMX_VIDEO_AVCLevel22;
5096                 break;
5097             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
5098                 *eLevel = OMX_VIDEO_AVCLevel3;
5099                 break;
5100             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
5101                 *eLevel = OMX_VIDEO_AVCLevel31;
5102                 break;
5103             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
5104                 *eLevel = OMX_VIDEO_AVCLevel32;
5105                 break;
5106             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
5107                 *eLevel = OMX_VIDEO_AVCLevel4;
5108                 break;
5109             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
5110                 *eLevel = OMX_VIDEO_AVCLevel41;
5111                 break;
5112             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
5113                 *eLevel = OMX_VIDEO_AVCLevel42;
5114                 break;
5115             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
5116                 *eLevel = OMX_VIDEO_AVCLevel5;
5117                 break;
5118             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
5119                 *eLevel = OMX_VIDEO_AVCLevel51;
5120                 break;
5121             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
5122                 *eLevel = OMX_VIDEO_AVCLevel52;
5123                 break;
5124             default :
5125                 *eLevel = OMX_VIDEO_AVCLevelMax;
5126                 status = false;
5127                 break;
5128         }
5129     }
5130     else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
5131         switch (codec_profile.profile) {
5132             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
5133                 *eProfile = OMX_VIDEO_VP8ProfileMain;
5134                 break;
5135             default:
5136                 *eProfile = OMX_VIDEO_VP8ProfileMax;
5137                 status = false;
5138                 break;
5139         }
5140         if (!status) {
5141             return status;
5142         }
5143 
5144         switch (profile_level.level) {
5145             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
5146                 *eLevel = OMX_VIDEO_VP8Level_Version0;
5147                 break;
5148             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
5149                 *eLevel = OMX_VIDEO_VP8Level_Version1;
5150                 break;
5151             default:
5152                 *eLevel = OMX_VIDEO_VP8LevelMax;
5153                 status = false;
5154                 break;
5155         }
5156     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5157         switch (codec_profile.profile) {
5158             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
5159                 *eProfile = OMX_VIDEO_HEVCProfileMain;
5160                 break;
5161             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
5162                 *eProfile = OMX_VIDEO_HEVCProfileMain10;
5163                 break;
5164             default:
5165                 *eProfile = OMX_VIDEO_HEVCProfileMax;
5166                 status = false;
5167                 break;
5168         }
5169         if (!status) {
5170             return status;
5171         }
5172 
5173         switch (profile_level.level) {
5174             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
5175                 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
5176                 break;
5177             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
5178                 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
5179                 break;
5180             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
5181                 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
5182                 break;
5183             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
5184                 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
5185                 break;
5186             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
5187                 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
5188                 break;
5189             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
5190                 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
5191                 break;
5192             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
5193                 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
5194                 break;
5195             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
5196                 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
5197                 break;
5198             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
5199                 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
5200                 break;
5201             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
5202                 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
5203                 break;
5204             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
5205                 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
5206                 break;
5207             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
5208                 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
5209                 break;
5210             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
5211                 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
5212                 break;
5213             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
5214                 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
5215                 break;
5216             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
5217                 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
5218                 break;
5219             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
5220                 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
5221                 break;
5222             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
5223                 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
5224                 break;
5225             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
5226                 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
5227                 break;
5228             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
5229                 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
5230                 break;
5231             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
5232                 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
5233                 break;
5234             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
5235                 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
5236                 break;
5237             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
5238                 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
5239                 break;
5240             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
5241                 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
5242                 break;
5243             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
5244                 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
5245                 break;
5246             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
5247                 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
5248                 break;
5249             default:
5250                 *eLevel = OMX_VIDEO_HEVCLevelMax;
5251                 status = false;
5252                 break;
5253         }
5254     }
5255 
5256     return status;
5257 }
5258 
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)5259 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
5260 {
5261     OMX_U32 new_profile = 0, new_level = 0;
5262     unsigned const int *profile_tbl = NULL;
5263     OMX_U32 mb_per_frame, mb_per_sec;
5264     bool profile_level_found = false;
5265 
5266     DEBUG_PRINT_LOW("Init profile table for respective codec");
5267 
5268     //validate the ht,width,fps,bitrate and set the appropriate profile and level
5269     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5270         if (*eProfile == 0) {
5271             if (!m_profile_set) {
5272                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
5273             } else {
5274                 switch (codec_profile.profile) {
5275                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
5276                         *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
5277                         break;
5278                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
5279                         *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
5280                         break;
5281                     default:
5282                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5283                         return false;
5284                 }
5285             }
5286         }
5287 
5288         if (*eLevel == 0 && !m_level_set) {
5289             *eLevel = OMX_VIDEO_MPEG4LevelMax;
5290         }
5291 
5292         if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
5293             profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
5294         } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
5295             profile_tbl = (unsigned int const *)
5296                 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
5297         } else {
5298             DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
5299             return false;
5300         }
5301     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5302         if (*eProfile == 0) {
5303             if (!m_profile_set) {
5304                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
5305             } else {
5306                 switch (codec_profile.profile) {
5307                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
5308                         *eProfile = OMX_VIDEO_AVCProfileBaseline;
5309                         break;
5310                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
5311                         *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
5312                         break;
5313                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
5314                         *eProfile = OMX_VIDEO_AVCProfileMain;
5315                         break;
5316                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
5317                         *eProfile = OMX_VIDEO_AVCProfileExtended;
5318                         break;
5319                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
5320                         *eProfile = OMX_VIDEO_AVCProfileHigh;
5321                         break;
5322                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
5323                         *eProfile = OMX_VIDEO_AVCProfileHigh10;
5324                         break;
5325                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
5326                         *eProfile = OMX_VIDEO_AVCProfileHigh422;
5327                         break;
5328                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
5329                         *eProfile = OMX_VIDEO_AVCProfileHigh444;
5330                         break;
5331                     default:
5332                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5333                         return false;
5334                 }
5335             }
5336         }
5337 
5338         if (*eLevel == 0 && !m_level_set) {
5339             *eLevel = OMX_VIDEO_AVCLevelMax;
5340         }
5341 
5342         if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
5343             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
5344             profile_tbl = (unsigned int const *)h264_profile_level_table;
5345         } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
5346             profile_tbl = (unsigned int const *)
5347                 (&h264_profile_level_table[H264_HP_START]);
5348         } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
5349             profile_tbl = (unsigned int const *)
5350                 (&h264_profile_level_table[H264_MP_START]);
5351         } else {
5352             DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
5353             return false;
5354         }
5355     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5356         if (*eProfile == 0) {
5357             if (!m_profile_set) {
5358                 *eProfile = OMX_VIDEO_H263ProfileBaseline;
5359             } else {
5360                 switch (codec_profile.profile) {
5361                     case VEN_PROFILE_H263_BASELINE:
5362                         *eProfile = OMX_VIDEO_H263ProfileBaseline;
5363                         break;
5364                     default:
5365                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5366                         return false;
5367                 }
5368             }
5369         }
5370 
5371         if (*eLevel == 0 && !m_level_set) {
5372             *eLevel = OMX_VIDEO_H263LevelMax;
5373         }
5374 
5375         if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
5376             profile_tbl = (unsigned int const *)h263_profile_level_table;
5377         } else {
5378             DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
5379             return false;
5380         }
5381     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
5382         if (*eProfile == 0) {
5383             *eProfile = OMX_VIDEO_VP8ProfileMain;
5384         } else {
5385             switch (codec_profile.profile) {
5386                 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
5387                     *eProfile = OMX_VIDEO_VP8ProfileMain;
5388                     break;
5389                 default:
5390                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
5391                     return false;
5392             }
5393         }
5394         if (*eLevel == 0) {
5395             switch (profile_level.level) {
5396                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
5397                     *eLevel = OMX_VIDEO_VP8Level_Version0;
5398                     break;
5399                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
5400                     *eLevel = OMX_VIDEO_VP8Level_Version1;
5401                     break;
5402                 default:
5403                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
5404                     return false;
5405             }
5406         }
5407         return true;
5408     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5409         if (*eProfile == 0) {
5410             if (!m_profile_set) {
5411                 *eProfile = OMX_VIDEO_HEVCProfileMain;
5412     } else {
5413                 switch (codec_profile.profile) {
5414                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
5415                         *eProfile = OMX_VIDEO_HEVCProfileMain;
5416                         break;
5417                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
5418                         *eProfile = OMX_VIDEO_HEVCProfileMain10;
5419                         break;
5420                     default:
5421                         DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
5422                         return false;
5423                 }
5424             }
5425         }
5426 
5427         if (*eLevel == 0 && !m_level_set) {
5428             *eLevel = OMX_VIDEO_HEVCLevelMax;
5429         }
5430 
5431         if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
5432             profile_tbl = (unsigned int const *)hevc_profile_level_table;
5433         } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
5434             profile_tbl = (unsigned int const *)
5435                 (&hevc_profile_level_table[HEVC_MAIN10_START]);
5436         } else {
5437             DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
5438             return false;
5439         }
5440     } else {
5441         DEBUG_PRINT_ERROR("Invalid codec type");
5442         return false;
5443     }
5444 
5445     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
5446         ((m_sVenc_cfg.dvs_width + 15)>> 4);
5447 
5448     if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
5449         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
5450             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
5451 
5452         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
5453             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
5454 
5455         {
5456             new_level = profile_level.level;
5457             new_profile = codec_profile.profile;
5458             return true;
5459         }
5460     }
5461 
5462     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
5463 
5464     bool h264, ltr, hlayers;
5465     unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
5466     h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
5467     ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
5468     hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
5469      ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
5470 
5471     /*  Hybrid HP reference buffers:
5472         layers = 1, 2 need 1 reference buffer
5473         layers = 3, 4 need 2 reference buffers
5474         layers = 5, 6 need 3 reference buffers
5475     */
5476 
5477     if(hier_layers.hier_mode == HIER_P_HYBRID)
5478         hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
5479 
5480     do {
5481         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
5482             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
5483                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
5484                     if (h264 && (ltr || hlayers || hybridp)) {
5485                         // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
5486                         new_level = (int)profile_tbl[3];
5487                         new_profile = (int)profile_tbl[4];
5488                         profile_level_found = true;
5489                         DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
5490                                         ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
5491                                         MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
5492                         break;
5493                     } else {
5494                     new_level = (int)profile_tbl[3];
5495                     new_profile = (int)profile_tbl[4];
5496                     profile_level_found = true;
5497                         DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
5498                     break;
5499                 }
5500             }
5501         }
5502         }
5503         profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
5504     } while (profile_tbl[0] != 0);
5505 
5506     if (profile_level_found != true) {
5507         DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
5508         return false;
5509     }
5510 
5511     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
5512             || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
5513             || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
5514         *eLevel = new_level;
5515     }
5516 
5517     DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
5518             "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
5519 
5520     return true;
5521 }
5522 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)5523 bool venc_dev::venc_set_meta_mode(bool mode)
5524 {
5525     metadatamode = mode;
5526     return true;
5527 }
5528 #endif
5529 
venc_is_video_session_supported(unsigned long width,unsigned long height)5530 bool venc_dev::venc_is_video_session_supported(unsigned long width,
5531         unsigned long height)
5532 {
5533     if ((width * height < capability.min_width *  capability.min_height) ||
5534             (width * height > capability.max_width *  capability.max_height)) {
5535         DEBUG_PRINT_ERROR(
5536                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
5537                 width, height, capability.min_width, capability.min_height,
5538                 capability.max_width, capability.max_height);
5539         return false;
5540     }
5541 
5542     DEBUG_PRINT_LOW("video session supported");
5543     return true;
5544 }
5545