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