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