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