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