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