1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2014, 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 <unistd.h>
33#include <fcntl.h>
34#include "video_encoder_device_v4l2.h"
35#include "omx_video_encoder.h"
36#include <media/msm_vidc.h>
37#ifdef USE_ION
38#include <linux/msm_ion.h>
39#endif
40#include <media/msm_media_info.h>
41#include <cutils/properties.h>
42#include <media/hardware/HardwareAPI.h>
43
44#ifdef _ANDROID_
45#include <media/hardware/HardwareAPI.h>
46#include <gralloc_priv.h>
47#endif
48
49#define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
50#define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
51
52#define MPEG4_SP_START 0
53#define MPEG4_ASP_START (MPEG4_SP_START + 10)
54#define H263_BP_START 0
55#define H264_BP_START 0
56#define H264_HP_START (H264_BP_START + 17)
57#define H264_MP_START (H264_BP_START + 34)
58#define POLL_TIMEOUT 1000
59#define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
60
61#define SZ_4K 0x1000
62#define SZ_1M 0x100000
63
64/* MPEG4 profile and level table*/
65static const unsigned int mpeg4_profile_level_table[][5]= {
66    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
67    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
68    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
69    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
70    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
71    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
72    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
73    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
74    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
75    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
76    {0,0,0,0,0},
77
78    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
79    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
80    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
81    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
82    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
83    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
84    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
85    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
86    {0,0,0,0,0},
87};
88
89/* H264 profile and level table*/
90static const unsigned int h264_profile_level_table[][5]= {
91    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
92    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
93    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
94    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
95    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
96    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
97    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
98    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
99    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
100    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
101    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
102    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
103    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
104    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline},
105    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline},
106    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline},
107    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline},
108    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
109    {0,0,0,0,0},
110
111    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
112    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
113    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
114    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
115    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
116    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
117    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
118    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
119    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
120    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
121    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
122    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
123    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh},
124    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh},
125    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh},
126    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh},
127    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh},
128    {0,0,0,0,0},
129
130    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
131    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
132    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
133    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
134    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
135    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
136    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
137    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
138    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
139    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
140    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
141    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
142    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain},
143    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain},
144    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain},
145    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain},
146    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
147    {0,0,0,0,0}
148
149};
150
151/* H263 profile and level table*/
152static const unsigned int h263_profile_level_table[][5]= {
153    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
154    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
155    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
156    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
157    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
158    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
159    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
160    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
161    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
162    {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
163    {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
164    {0,0,0,0,0}
165};
166
167#define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
168#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
169
170#define BUFFER_LOG_LOC "/data/misc/media"
171
172//constructor
173venc_dev::venc_dev(class omx_venc *venc_class)
174{
175    //nothing to do
176    int i = 0;
177    venc_handle = venc_class;
178    etb = ebd = ftb = fbd = 0;
179
180    for (i = 0; i < MAX_PORT; i++)
181        streaming[i] = false;
182
183    stopped = 1;
184    paused = false;
185    async_thread_created = false;
186    color_format = 0;
187    pthread_mutex_init(&pause_resume_mlock, NULL);
188    pthread_cond_init(&pause_resume_cond, NULL);
189    memset(&extradata_info, 0, sizeof(extradata_info));
190    memset(&idrperiod, 0, sizeof(idrperiod));
191    memset(&multislice, 0, sizeof(multislice));
192    memset (&slice_mode, 0 , sizeof(slice_mode));
193    memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
194    memset(&rate_ctrl, 0, sizeof(rate_ctrl));
195    memset(&bitrate, 0, sizeof(bitrate));
196    memset(&intra_period, 0, sizeof(intra_period));
197    memset(&codec_profile, 0, sizeof(codec_profile));
198    memset(&set_param, 0, sizeof(set_param));
199    memset(&time_inc, 0, sizeof(time_inc));
200    memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
201    memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
202    memset(&session_qp, 0, sizeof(session_qp));
203    memset(&entropy, 0, sizeof(entropy));
204    memset(&dbkfilter, 0, sizeof(dbkfilter));
205    memset(&intra_refresh, 0, sizeof(intra_refresh));
206    memset(&hec, 0, sizeof(hec));
207    memset(&voptimecfg, 0, sizeof(voptimecfg));
208    memset(&capability, 0, sizeof(capability));
209    memset(&m_debug,0,sizeof(m_debug));
210    memset(&hier_p_layers,0,sizeof(hier_p_layers));
211    memset(&display_info,0,sizeof(display_info));
212    is_searchrange_set = false;
213    enable_mv_narrow_searchrange = false;
214
215    char property_value[PROPERTY_VALUE_MAX] = {0};
216    property_get("vidc.enc.log.in", property_value, "0");
217    m_debug.in_buffer_log = atoi(property_value);
218
219    property_get("vidc.enc.log.out", property_value, "0");
220    m_debug.out_buffer_log = atoi(property_value);
221
222    property_get("vidc.enc.log.extradata", property_value, "0");
223    m_debug.extradata_log = atoi(property_value);
224
225    snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
226             "%s", BUFFER_LOG_LOC);
227}
228
229venc_dev::~venc_dev()
230{
231    //nothing to do
232}
233
234void* venc_dev::async_venc_message_thread (void *input)
235{
236    struct venc_msg venc_msg;
237    omx_video* omx_venc_base = NULL;
238    omx_venc *omx = reinterpret_cast<omx_venc*>(input);
239    omx_venc_base = reinterpret_cast<omx_video*>(input);
240    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
241
242    prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
243    struct v4l2_plane plane[VIDEO_MAX_PLANES];
244    struct pollfd pfd;
245    struct v4l2_buffer v4l2_buf;
246    struct v4l2_event dqevent;
247    pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
248    pfd.fd = omx->handle->m_nDriver_fd;
249    int error_code = 0,rc=0;
250
251    memset(&v4l2_buf, 0, sizeof(v4l2_buf));
252
253    while (1) {
254        pthread_mutex_lock(&omx->handle->pause_resume_mlock);
255
256        if (omx->handle->paused) {
257            venc_msg.msgcode = VEN_MSG_PAUSE;
258            venc_msg.statuscode = VEN_S_SUCCESS;
259
260            if (omx->async_message_process(input, &venc_msg) < 0) {
261                DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
262                pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
263                break;
264            }
265
266            /* Block here until the IL client resumes us again */
267            pthread_cond_wait(&omx->handle->pause_resume_cond,
268                    &omx->handle->pause_resume_mlock);
269
270            venc_msg.msgcode = VEN_MSG_RESUME;
271            venc_msg.statuscode = VEN_S_SUCCESS;
272
273            if (omx->async_message_process(input, &venc_msg) < 0) {
274                DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
275                pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
276                break;
277            }
278        }
279
280        pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
281
282        rc = poll(&pfd, 1, POLL_TIMEOUT);
283
284        if (!rc) {
285            DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
286                    omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
287            continue;
288        } else if (rc < 0) {
289            DEBUG_PRINT_ERROR("Error while polling: %d", rc);
290            break;
291        }
292
293        if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
294            v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
295            v4l2_buf.memory = V4L2_MEMORY_USERPTR;
296            v4l2_buf.length = omx->handle->num_planes;
297            v4l2_buf.m.planes = plane;
298
299            while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
300                venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
301                venc_msg.statuscode=VEN_S_SUCCESS;
302                omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
303                venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
304                venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
305                venc_msg.buf.flags = 0;
306                venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
307                venc_msg.buf.clientdata=(void*)omxhdr;
308                venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
309
310                /* TODO: ideally report other types of frames as well
311                 * for now it doesn't look like IL client cares about
312                 * other types
313                 */
314                if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
315                    venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
316
317                if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
318                    venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
319
320                if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
321                    venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
322
323                if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
324                    venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
325
326                if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
327                    venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
328
329                if (omxhdr->nFilledLen)
330                    venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
331
332                omx->handle->fbd++;
333
334                if (omx->async_message_process(input,&venc_msg) < 0) {
335                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
336                    break;
337                }
338            }
339        }
340
341        if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
342            v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
343            v4l2_buf.memory = V4L2_MEMORY_USERPTR;
344            v4l2_buf.m.planes = plane;
345            v4l2_buf.length = 1;
346
347            while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
348                venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
349                venc_msg.statuscode=VEN_S_SUCCESS;
350                omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
351                venc_msg.buf.clientdata=(void*)omxhdr;
352                omx->handle->ebd++;
353
354                if (omx->async_message_process(input,&venc_msg) < 0) {
355                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
356                    break;
357                }
358            }
359        }
360
361        if (pfd.revents & POLLPRI) {
362            rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
363
364            if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
365                DEBUG_PRINT_HIGH("CLOSE DONE");
366                break;
367            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
368                venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
369                venc_msg.statuscode = VEN_S_SUCCESS;
370
371                if (omx->async_message_process(input,&venc_msg) < 0) {
372                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
373                    break;
374                }
375
376                venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
377                venc_msg.statuscode = VEN_S_SUCCESS;
378
379                if (omx->async_message_process(input,&venc_msg) < 0) {
380                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
381                    break;
382                }
383            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
384                DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
385                venc_msg.msgcode = VEN_MSG_INDICATION;
386                venc_msg.statuscode=VEN_S_EFAIL;
387
388                if (omx->async_message_process(input,&venc_msg) < 0) {
389                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
390                    break;
391                }
392            }
393        }
394    }
395
396    DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
397    return NULL;
398}
399
400static const int event_type[] = {
401    V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
402    V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
403    V4L2_EVENT_MSM_VIDC_SYS_ERROR
404};
405
406static OMX_ERRORTYPE subscribe_to_events(int fd)
407{
408    OMX_ERRORTYPE eRet = OMX_ErrorNone;
409    struct v4l2_event_subscription sub;
410    int array_sz = sizeof(event_type)/sizeof(int);
411    int i,rc;
412    memset(&sub, 0, sizeof(sub));
413
414    if (fd < 0) {
415       DEBUG_PRINT_ERROR("Invalid input: %d", fd);
416        return OMX_ErrorBadParameter;
417    }
418
419    for (i = 0; i < array_sz; ++i) {
420        memset(&sub, 0, sizeof(sub));
421        sub.type = event_type[i];
422        rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
423
424        if (rc) {
425           DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
426            break;
427        }
428    }
429
430    if (i < array_sz) {
431        for (--i; i >=0 ; i--) {
432            memset(&sub, 0, sizeof(sub));
433            sub.type = event_type[i];
434            rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
435
436            if (rc)
437               DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
438        }
439
440        eRet = OMX_ErrorNotImplemented;
441    }
442
443    return eRet;
444}
445
446int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
447{
448    OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
449
450    if (!dst || !src)
451        return 0;
452
453    /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
454     * targets, since the payload format will be different */
455    mbi->nFormat = 1;
456    mbi->nDataSize = src->data_size;
457    memcpy(&mbi->data, &src->data, src->data_size);
458
459    return mbi->nDataSize + sizeof(*mbi);
460}
461
462bool venc_dev::handle_extradata(void *buffer, int index)
463{
464    OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
465    OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
466
467    if (!extradata_info.uaddr) {
468        DEBUG_PRINT_ERROR("Extradata buffers not allocated");
469        return false;
470    }
471
472    p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
473                p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
474
475    if (extradata_info.buffer_size >
476            p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
477        DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
478        p_extra = NULL;
479        return false;
480    } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
481        /* A lot of the code below assumes this condition, so error out if it's not met */
482        DEBUG_PRINT_ERROR("Extradata ABI mismatch");
483        return false;
484    }
485
486    struct msm_vidc_extradata_header *p_extradata = NULL;
487    do {
488        p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
489            ((char *)p_extradata) + p_extradata->size :
490            extradata_info.uaddr + index * extradata_info.buffer_size);
491
492        switch (p_extradata->type) {
493            case MSM_VIDC_EXTRADATA_METADATA_MBI:
494            {
495                OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
496                p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
497                p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
498                p_extra->nPortIndex = OMX_DirOutput;
499                p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
500                p_extra->nDataSize = payloadSize;
501                break;
502            }
503            case MSM_VIDC_EXTRADATA_NONE:
504                p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
505                p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
506                p_extra->nPortIndex = OMX_DirOutput;
507                p_extra->eType = OMX_ExtraDataNone;
508                p_extra->nDataSize = 0;
509                break;
510            default:
511                /* No idea what this stuff is, just skip over it */
512                DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
513                        p_extradata->type);
514                continue;
515        }
516
517        p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
518    } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
519
520    /* Just for debugging: Traverse the list of extra datas  and spit it out onto log */
521    p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
522                p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
523    while(p_extra->eType != OMX_ExtraDataNone)
524    {
525        DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
526                p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
527                (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
528
529        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
530                p_extra->nSize);
531    }
532
533    return true;
534}
535
536int venc_dev::venc_set_format(int format)
537{
538    int rc = true;
539
540    if (format)
541        color_format = format;
542    else {
543        color_format = 0;
544        rc = false;
545    }
546
547    return rc;
548}
549
550OMX_ERRORTYPE venc_dev::allocate_extradata()
551{
552    if (extradata_info.allocated) {
553        DEBUG_PRINT_ERROR("Extradata already allocated!");
554        return OMX_ErrorNone;
555    }
556
557#ifdef USE_ION
558
559    if (extradata_info.buffer_size) {
560        if (extradata_info.ion.ion_alloc_data.handle) {
561            munmap((void *)extradata_info.uaddr, extradata_info.size);
562            close(extradata_info.ion.fd_ion_data.fd);
563            venc_handle->free_ion_memory(&extradata_info.ion);
564        }
565
566        extradata_info.size = ALIGN(extradata_info.size, SZ_4K);
567
568        extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory(
569                extradata_info.size,
570                &extradata_info.ion.ion_alloc_data,
571                &extradata_info.ion.fd_ion_data, 0);
572
573        if (extradata_info.ion.ion_device_fd < 0) {
574            DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
575            return OMX_ErrorInsufficientResources;
576        }
577
578        extradata_info.uaddr = (char *)mmap(NULL,
579                extradata_info.size,
580                PROT_READ|PROT_WRITE, MAP_SHARED,
581                extradata_info.ion.fd_ion_data.fd , 0);
582
583        if (extradata_info.uaddr == MAP_FAILED) {
584            DEBUG_PRINT_ERROR("Failed to map extradata memory");
585            close(extradata_info.ion.fd_ion_data.fd);
586            venc_handle->free_ion_memory(&extradata_info.ion);
587            return OMX_ErrorInsufficientResources;
588        }
589    }
590
591#endif
592    extradata_info.allocated = 1;
593    return OMX_ErrorNone;
594}
595
596void venc_dev::free_extradata()
597{
598#ifdef USE_ION
599
600    if (extradata_info.uaddr) {
601        munmap((void *)extradata_info.uaddr, extradata_info.size);
602        close(extradata_info.ion.fd_ion_data.fd);
603        venc_handle->free_ion_memory(&extradata_info.ion);
604    }
605
606    memset(&extradata_info, 0, sizeof(extradata_info));
607#endif
608}
609
610bool venc_dev::venc_get_output_log_flag()
611{
612    return (m_debug.out_buffer_log == 1);
613}
614
615int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
616{
617    if (!m_debug.outfile) {
618        int size = 0;
619        if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
620           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
621                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
622        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
623           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
624                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
625        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
626           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
627                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
628        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
629           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
630                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
631        }
632        if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
633             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
634                                m_debug.outfile_name, size);
635        }
636        m_debug.outfile = fopen(m_debug.outfile_name, "ab");
637        if (!m_debug.outfile) {
638            DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
639                               m_debug.outfile_name, errno);
640            m_debug.outfile_name[0] = '\0';
641            return -1;
642        }
643    }
644    if (m_debug.outfile && buffer_len) {
645        DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
646        fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
647    }
648    return 0;
649}
650
651int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
652{
653    if (!m_debug.extradatafile && m_debug.extradata_log) {
654        int size = 0;
655        if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
656           size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
657                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
658        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
659           size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
660                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
661        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
662           size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
663                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
664        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
665           size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
666                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
667        }
668        if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
669             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
670                                m_debug.extradatafile_name, size);
671        }
672
673        m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
674        if (!m_debug.extradatafile) {
675            DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
676                               m_debug.extradatafile_name, errno);
677            m_debug.extradatafile_name[0] = '\0';
678            return -1;
679        }
680    }
681
682    if (m_debug.extradatafile) {
683        OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
684        do {
685            p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
686                    ((char *)p_extra) + p_extra->nSize);
687            fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
688        } while (p_extra->eType != OMX_ExtraDataNone);
689    }
690    return 0;
691}
692
693int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) {
694    if (!m_debug.infile) {
695        int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
696                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
697        if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
698             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
699                                m_debug.infile_name, size);
700        }
701        m_debug.infile = fopen (m_debug.infile_name, "ab");
702        if (!m_debug.infile) {
703            DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
704            m_debug.infile_name[0] = '\0';
705            return -1;
706        }
707    }
708    if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
709        unsigned long i, msize;
710        int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
711        int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
712        unsigned char *pvirt,*ptemp;
713
714        char *temp = (char *)pbuffer->pBuffer;
715
716        msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
717        if (metadatamode == 1) {
718            pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
719            if (pvirt) {
720               ptemp = pvirt;
721               for (i = 0; i < m_sVenc_cfg.input_height; i++) {
722                    fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
723                    ptemp += stride;
724               }
725               ptemp = pvirt + (stride * scanlines);
726               for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
727                   fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
728                   ptemp += stride;
729               }
730               munmap(pvirt, msize);
731             } else if (pvirt == MAP_FAILED) {
732                 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
733                 return -1;
734             }
735        } else {
736            for (i = 0; i < m_sVenc_cfg.input_height; i++) {
737                 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
738                 temp += stride;
739            }
740
741            temp = (char *)pbuffer->pBuffer + (stride * scanlines);
742
743            for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
744                fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
745                temp += stride;
746            }
747        }
748    }
749    return 0;
750}
751
752bool venc_dev::venc_open(OMX_U32 codec)
753{
754    int r;
755    unsigned int alignment = 0,buffer_size = 0, temp =0;
756    struct v4l2_control control;
757    OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc";
758
759    char platform_name[PROPERTY_VALUE_MAX];
760    property_get("ro.board.platform", platform_name, "0");
761
762    if (!strncmp(platform_name, "msm8610", 7)) {
763        device_name = (OMX_STRING)"/dev/video/q6_enc";
764    }
765    if (!strncmp(platform_name, "msm8916", 7)) {
766        enable_mv_narrow_searchrange = true;
767        sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
768                        ISurfaceComposer::eDisplayIdMain));
769        SurfaceComposerClient::getDisplayInfo(display, &display_info);
770        DEBUG_PRINT_LOW("Display panel resolution %dX%d",
771            display_info.w, display_info.h);
772    }
773    m_nDriver_fd = open (device_name, O_RDWR);
774
775    if (m_nDriver_fd == 0) {
776        DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
777        m_nDriver_fd = open (device_name, O_RDWR);
778    }
779
780    if ((int)m_nDriver_fd < 0) {
781        DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
782        return false;
783    }
784
785    DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
786    // set the basic configuration of the video encoder driver
787    m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
788    m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
789    m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
790    m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
791    m_sVenc_cfg.fps_num = 30;
792    m_sVenc_cfg.fps_den = 1;
793    m_sVenc_cfg.targetbitrate = 64000;
794    m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
795    m_codec = codec;
796
797    if (codec == OMX_VIDEO_CodingMPEG4) {
798        m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
799        codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
800        profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
801        session_qp_range.minqp = 1;
802        session_qp_range.maxqp = 31;
803    } else if (codec == OMX_VIDEO_CodingH263) {
804        m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
805        codec_profile.profile = VEN_PROFILE_H263_BASELINE;
806        profile_level.level = VEN_LEVEL_H263_20;
807        session_qp_range.minqp = 1;
808        session_qp_range.maxqp = 31;
809    } else if (codec == OMX_VIDEO_CodingAVC) {
810        m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
811        codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
812        profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
813        session_qp_range.minqp = 1;
814        session_qp_range.maxqp = 51;
815    } else if (codec == OMX_VIDEO_CodingVP8) {
816        m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
817        codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
818        profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
819        session_qp_range.minqp = 1;
820        session_qp_range.maxqp = 128;
821    }
822    session_qp_values.minqp = session_qp_range.minqp;
823    session_qp_values.maxqp = session_qp_range.maxqp;
824
825    int ret;
826    ret = subscribe_to_events(m_nDriver_fd);
827
828    if (ret) {
829        DEBUG_PRINT_ERROR("Subscribe Event Failed");
830        return false;
831    }
832
833    struct v4l2_capability cap;
834
835    struct v4l2_fmtdesc fdesc;
836
837    struct v4l2_format fmt;
838
839    struct v4l2_requestbuffers bufreq;
840
841    ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
842
843    if (ret) {
844        DEBUG_PRINT_ERROR("Failed to query capabilities");
845    } else {
846        DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
847                " version = %d, capabilities = %x", cap.driver, cap.card,
848                cap.bus_info, cap.version, cap.capabilities);
849    }
850
851    ret=0;
852    fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
853    fdesc.index=0;
854
855    while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
856        DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
857                fdesc.pixelformat, fdesc.flags);
858        fdesc.index++;
859    }
860
861    fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
862    fdesc.index=0;
863
864    while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
865        DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
866                fdesc.pixelformat, fdesc.flags);
867        fdesc.index++;
868    }
869
870    if (venc_handle->is_secure_session()) {
871        m_sOutput_buff_property.alignment = SZ_1M;
872        m_sInput_buff_property.alignment  = SZ_1M;
873    } else {
874        m_sOutput_buff_property.alignment = SZ_4K;
875        m_sInput_buff_property.alignment  = SZ_4K;
876    }
877    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
878    fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
879    fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
880    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
881
882    /*TODO: Return values not handled properly in this function anywhere.
883     * Need to handle those.*/
884    ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
885
886    if (ret) {
887        DEBUG_PRINT_ERROR("Failed to set format on capture port");
888        return false;
889    }
890
891    m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
892
893    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
894    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
895    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
896    fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
897
898    ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
899    m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
900
901    bufreq.memory = V4L2_MEMORY_USERPTR;
902    bufreq.count = 2;
903
904    bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
905    ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
906    m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
907
908    bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
909    bufreq.count = 2;
910    ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
911    m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
912
913    if(venc_handle->is_secure_session()) {
914        control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
915        control.value = 1;
916        DEBUG_PRINT_HIGH("ioctl: open secure device");
917        ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
918        if (ret) {
919            DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
920            return false;
921        }
922    }
923
924    resume_in_stopped = 0;
925    metadatamode = 0;
926
927    control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
928    control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
929
930    DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
931
932    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
933        DEBUG_PRINT_ERROR("Failed to set control");
934
935    struct v4l2_frmsizeenum frmsize;
936
937    //Get the hardware capabilities
938    memset((void *)&frmsize,0,sizeof(frmsize));
939    frmsize.index = 0;
940    frmsize.pixel_format = m_sVenc_cfg.codectype;
941    ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
942
943    if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
944        DEBUG_PRINT_ERROR("Failed to get framesizes");
945        return false;
946    }
947
948    if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
949        capability.min_width = frmsize.stepwise.min_width;
950        capability.max_width = frmsize.stepwise.max_width;
951        capability.min_height = frmsize.stepwise.min_height;
952        capability.max_height = frmsize.stepwise.max_height;
953    }
954    //Initialize non-default parameters
955    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
956        control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
957        control.value = 0x7fffffff;
958        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
959            DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
960    }
961
962    return true;
963}
964
965
966static OMX_ERRORTYPE unsubscribe_to_events(int fd)
967{
968    OMX_ERRORTYPE eRet = OMX_ErrorNone;
969    struct v4l2_event_subscription sub;
970    int array_sz = sizeof(event_type)/sizeof(int);
971    int i,rc;
972
973    if (fd < 0) {
974       DEBUG_PRINT_ERROR("Invalid input: %d", fd);
975        return OMX_ErrorBadParameter;
976    }
977
978    for (i = 0; i < array_sz; ++i) {
979        memset(&sub, 0, sizeof(sub));
980        sub.type = event_type[i];
981        rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
982
983        if (rc) {
984           DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
985            break;
986        }
987    }
988
989    return eRet;
990}
991
992void venc_dev::venc_close()
993{
994    struct v4l2_encoder_cmd enc;
995    DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
996
997    if ((int)m_nDriver_fd >= 0) {
998        enc.cmd = V4L2_ENC_CMD_STOP;
999        ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
1000        DEBUG_PRINT_HIGH("venc_close E");
1001
1002        if (async_thread_created)
1003            pthread_join(m_tid,NULL);
1004
1005        DEBUG_PRINT_HIGH("venc_close X");
1006        unsubscribe_to_events(m_nDriver_fd);
1007        close(m_nDriver_fd);
1008        m_nDriver_fd = -1;
1009    }
1010
1011    if (m_debug.infile) {
1012        fclose(m_debug.infile);
1013        m_debug.infile = NULL;
1014    }
1015
1016    if (m_debug.outfile) {
1017        fclose(m_debug.outfile);
1018        m_debug.outfile = NULL;
1019    }
1020
1021    if (m_debug.extradatafile) {
1022        fclose(m_debug.extradatafile);
1023        m_debug.extradatafile = NULL;
1024    }
1025}
1026
1027bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1028        OMX_U32 *actual_buff_count,
1029        OMX_U32 *buff_size,
1030        OMX_U32 port)
1031{
1032    (void)min_buff_count, (void)buff_size;
1033    unsigned long temp_count = 0;
1034
1035    if (port == 0) {
1036        if (*actual_buff_count > m_sInput_buff_property.mincount) {
1037            temp_count = m_sInput_buff_property.actualcount;
1038            m_sInput_buff_property.actualcount = *actual_buff_count;
1039            DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1040        }
1041    } else {
1042        if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1043            temp_count = m_sOutput_buff_property.actualcount;
1044            m_sOutput_buff_property.actualcount = *actual_buff_count;
1045            DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1046        }
1047    }
1048
1049    return true;
1050
1051}
1052
1053bool venc_dev::venc_loaded_start()
1054{
1055    return true;
1056}
1057
1058bool venc_dev::venc_loaded_stop()
1059{
1060    return true;
1061}
1062
1063bool venc_dev::venc_loaded_start_done()
1064{
1065    return true;
1066}
1067
1068bool venc_dev::venc_loaded_stop_done()
1069{
1070    return true;
1071}
1072
1073bool venc_dev::venc_get_seq_hdr(void *buffer,
1074        unsigned buffer_size, OMX_U32 *header_len)
1075{
1076    (void) buffer, (void) buffer_size, (void) header_len;
1077    return true;
1078}
1079
1080bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1081        OMX_U32 *actual_buff_count,
1082        OMX_U32 *buff_size,
1083        OMX_U32 port)
1084{
1085    struct v4l2_format fmt;
1086    struct v4l2_requestbuffers bufreq;
1087    unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1088    int ret;
1089
1090    if (port == 0) {
1091        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1092        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1093        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1094        fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1095        ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1096        m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1097        bufreq.memory = V4L2_MEMORY_USERPTR;
1098
1099        if (*actual_buff_count)
1100            bufreq.count = *actual_buff_count;
1101        else
1102            bufreq.count = 2;
1103
1104        bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1105        ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1106
1107        if (ret) {
1108            DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1109            return false;
1110        }
1111
1112        m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1113        *min_buff_count = m_sInput_buff_property.mincount;
1114        *actual_buff_count = m_sInput_buff_property.actualcount;
1115#ifdef USE_ION
1116        // For ION memory allocations of the allocated buffer size
1117        // must be 4k aligned, hence aligning the input buffer
1118        // size to 4k.
1119        m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1120#endif
1121        *buff_size = m_sInput_buff_property.datasize;
1122    } else {
1123        int extra_idx = 0;
1124        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1125        fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1126        fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1127        fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1128
1129        ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1130        m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1131        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1132        fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1133        fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1134        fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1135
1136        ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1137        m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1138        bufreq.memory = V4L2_MEMORY_USERPTR;
1139
1140        if (*actual_buff_count)
1141            bufreq.count = *actual_buff_count;
1142        else
1143            bufreq.count = 2;
1144
1145        bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1146        ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1147
1148        if (ret) {
1149            DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1150            return false;
1151        }
1152
1153        m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1154        *min_buff_count = m_sOutput_buff_property.mincount;
1155        *actual_buff_count = m_sOutput_buff_property.actualcount;
1156        *buff_size = m_sOutput_buff_property.datasize;
1157        num_planes = fmt.fmt.pix_mp.num_planes;
1158        extra_idx = EXTRADATA_IDX(num_planes);
1159
1160        if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1161            extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1162        } else if (extra_idx >= VIDEO_MAX_PLANES) {
1163            DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1164            return OMX_ErrorBadParameter;
1165        }
1166
1167        extradata_info.buffer_size = extra_data_size;
1168        extradata_info.count = m_sOutput_buff_property.actualcount;
1169        extradata_info.size = extradata_info.buffer_size * extradata_info.count;
1170    }
1171
1172    return true;
1173}
1174
1175bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
1176{
1177    DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1178    struct v4l2_format fmt;
1179    struct v4l2_requestbuffers bufreq;
1180    int ret;
1181
1182    switch ((int)index) {
1183        case OMX_IndexParamPortDefinition:
1184            {
1185                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1186                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1187                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1188
1189                if (portDefn->nPortIndex == PORT_INDEX_IN) {
1190                    if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1191                        return false;
1192                    }
1193
1194                    if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1195                        return false;
1196                    }
1197                    if ((display_info.w * display_info.h) > (OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
1198                        && enable_mv_narrow_searchrange &&
1199                        (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1200                        (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1201                        if (venc_set_searchrange() == false) {
1202                            DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1203                        }
1204                    }
1205                    if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1206                            m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1207                        DEBUG_PRINT_LOW("Basic parameter has changed");
1208                        m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1209                        m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1210                        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1211                        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1212                        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1213                        fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1214
1215                        if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1216                            DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1217                            return false;
1218                        }
1219
1220                        m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1221                        bufreq.memory = V4L2_MEMORY_USERPTR;
1222                        bufreq.count = portDefn->nBufferCountActual;
1223                        bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1224
1225                        if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1226                            DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1227                            return false;
1228                        }
1229
1230                        if (bufreq.count == portDefn->nBufferCountActual)
1231                            m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1232
1233                        if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1234                            m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1235                    }
1236
1237                    DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1238                            (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1239                } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1240                    m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1241                    m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1242                    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1243                    fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1244                    fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1245                    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1246
1247                    if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1248                        DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1249                        return false;
1250                    }
1251
1252                    m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1253
1254                    if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1255                        return false;
1256                    }
1257
1258                        m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1259                        bufreq.memory = V4L2_MEMORY_USERPTR;
1260                        bufreq.count = portDefn->nBufferCountActual;
1261                        bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1262
1263                        if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1264                            DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1265                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1266                            return false;
1267                        }
1268
1269                        if (bufreq.count == portDefn->nBufferCountActual)
1270                            m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1271
1272                        if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1273                            m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1274
1275                        if (num_planes > 1)
1276                            extradata_info.count = m_sOutput_buff_property.actualcount;
1277
1278                    DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1279                            (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1280                } else {
1281                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1282                }
1283
1284                break;
1285            }
1286        case OMX_IndexParamVideoPortFormat:
1287            {
1288                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1289                portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1290                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1291
1292                if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1293                    if (!venc_set_color_format(portFmt->eColorFormat)) {
1294                        return false;
1295                    }
1296                } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1297                    if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1298                        return false;
1299                    }
1300                } else {
1301                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1302                }
1303
1304                break;
1305            }
1306        case OMX_IndexParamVideoBitrate:
1307            {
1308                OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1309                pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1310                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1311
1312                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1313                    if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1314                        DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1315                        return false;
1316                    }
1317
1318                    if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1319                        DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1320                        return false;
1321                    }
1322                } else {
1323                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1324                }
1325
1326                break;
1327            }
1328        case OMX_IndexParamVideoMpeg4:
1329            {
1330                OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1331                OMX_U32 bFrames = 0;
1332
1333                pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1334                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1335
1336                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1337                    if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1338                        DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1339                        return false;
1340                    }
1341
1342                    m_profile_set = false;
1343                    m_level_set = false;
1344
1345                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1346                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1347                        return false;
1348                    } else {
1349                        if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1350                            if (pParam->nBFrames) {
1351                                bFrames = pParam->nBFrames;
1352                            }
1353                        } else {
1354                            if (pParam->nBFrames) {
1355                                DEBUG_PRINT_ERROR("Warning: B frames not supported");
1356                                bFrames = 0;
1357                            }
1358                        }
1359                    }
1360
1361                    if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
1362                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1363                        return false;
1364                    }
1365
1366                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1367                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1368                        return false;
1369                    }
1370                } else {
1371                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1372                }
1373
1374                break;
1375            }
1376        case OMX_IndexParamVideoH263:
1377            {
1378                OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1379                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1380                OMX_U32 bFrames = 0;
1381
1382                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1383                    m_profile_set = false;
1384                    m_level_set = false;
1385
1386                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1387                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1388                        return false;
1389                    }
1390
1391                    if (pParam->nBFrames)
1392                        DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1393
1394                    if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
1395                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1396                        return false;
1397                    }
1398                } else {
1399                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1400                }
1401
1402                break;
1403            }
1404        case OMX_IndexParamVideoAvc:
1405            {
1406                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1407                OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1408                OMX_U32 bFrames = 0;
1409
1410                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1411                    DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1412                            pParam->eProfile,pParam->eLevel);
1413
1414                    m_profile_set = false;
1415                    m_level_set = false;
1416
1417                    if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1418                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1419                                pParam->eProfile, pParam->eLevel);
1420                        return false;
1421                    } else {
1422                        if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1423                            (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1424                            if (pParam->nBFrames) {
1425                                bFrames = pParam->nBFrames;
1426                            }
1427                        } else {
1428                            if (pParam->nBFrames) {
1429                                DEBUG_PRINT_ERROR("Warning: B frames not supported");
1430                                bFrames = 0;
1431                            }
1432                        }
1433                    }
1434
1435                    if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
1436                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1437                        return false;
1438                    }
1439
1440                    if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1441                        DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1442                        return false;
1443                    }
1444
1445                    if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1446                        DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1447                        return false;
1448                    }
1449
1450                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1451                        DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1452                        return false;
1453                    }
1454                } else {
1455                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1456                }
1457
1458                //TBD, lot of other variables to be updated, yet to decide
1459                break;
1460            }
1461        case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1462            {
1463                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1464                OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1465                if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1466                    DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1467                                        pParam->eProfile, pParam->eLevel);
1468                    return false;
1469                }
1470
1471                if(!venc_set_ltrmode(1, 1)) {
1472                   DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1473                   return false;
1474                }
1475
1476                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1477                 // Disable hier-p if ltr is enabled.
1478                 if (m_codec == OMX_VIDEO_CodingVP8) {
1479                     DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1480                     if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1481                        DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1482                     }
1483                 }
1484
1485                break;
1486            }
1487        case OMX_IndexParamVideoIntraRefresh:
1488            {
1489                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1490                OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1491                    (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1492
1493                if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1494                    if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1495                        DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1496                        return false;
1497                    }
1498                } else {
1499                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1500                }
1501
1502                break;
1503            }
1504        case OMX_IndexParamVideoErrorCorrection:
1505            {
1506                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1507                OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1508                    (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1509
1510                if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1511                    if (venc_set_error_resilience(error_resilience) == false) {
1512                        DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1513                        return false;
1514                    }
1515                } else {
1516                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1517                }
1518
1519                break;
1520            }
1521        case OMX_IndexParamVideoProfileLevelCurrent:
1522            {
1523                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1524                OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1525                    (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1526
1527                if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1528                    m_profile_set = false;
1529                    m_level_set = false;
1530
1531                    if (!venc_set_profile_level (profile_level->eProfile,
1532                                profile_level->eLevel)) {
1533                        DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1534                        return false;
1535                    }
1536                } else {
1537                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1538                }
1539
1540                break;
1541            }
1542        case OMX_IndexParamVideoQuantization:
1543            {
1544                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
1545                OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1546                    (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1547                if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1548                    if (venc_set_session_qp (session_qp->nQpI,
1549                                session_qp->nQpP,
1550                                session_qp->nQpB) == false) {
1551                        DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
1552                        return false;
1553                    }
1554                } else {
1555                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1556                }
1557
1558                break;
1559            }
1560        case QOMX_IndexParamVideoInitialQp:
1561            {
1562                QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
1563                    (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
1564                 if (initqp->bEnableInitQp) {
1565                    DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
1566                    if(venc_enable_initial_qp(initqp) == false) {
1567                       DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
1568                       return OMX_ErrorUnsupportedSetting;
1569                     }
1570                 } else
1571                    DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
1572                break;
1573            }
1574        case OMX_QcomIndexParamVideoQPRange:
1575            {
1576                DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
1577                OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
1578                    (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
1579
1580                if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1581                    if(venc_set_session_qp_range (session_qp_range->minQP,
1582                                session_qp_range->maxQP) == false) {
1583                        DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
1584                            (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
1585                        return false;
1586                    } else {
1587                        session_qp_values.minqp = session_qp_range->minQP;
1588                        session_qp_values.maxqp = session_qp_range->maxQP;
1589                    }
1590                } else {
1591                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1592                }
1593
1594                break;
1595            }
1596        case OMX_QcomIndexEnableSliceDeliveryMode:
1597            {
1598                QOMX_EXTNINDEX_PARAMTYPE* pParam =
1599                    (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1600
1601                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1602                    if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1603                        DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1604                        return OMX_ErrorUnsupportedSetting;
1605                    }
1606                } else {
1607                    DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1608                            "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
1609                    return OMX_ErrorBadPortIndex;
1610                }
1611
1612                break;
1613            }
1614        case OMX_ExtraDataVideoEncoderSliceInfo:
1615            {
1616                DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1617                OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1618
1619                if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
1620                    DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
1621                    return false;
1622                }
1623
1624                extradata = true;
1625                break;
1626            }
1627        case OMX_ExtraDataVideoEncoderMBInfo:
1628            {
1629                DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
1630                OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
1631
1632                if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
1633                    DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
1634                    return false;
1635                }
1636
1637                extradata = true;
1638                break;
1639            }
1640        case OMX_QcomIndexParamSequenceHeaderWithIDR:
1641            {
1642                PrependSPSPPSToIDRFramesParams * pParam =
1643                    (PrependSPSPPSToIDRFramesParams *)paramData;
1644
1645                DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
1646                if(venc_set_inband_video_header(pParam->bEnable) == false) {
1647                    DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
1648                    return OMX_ErrorUnsupportedSetting;
1649                }
1650
1651                break;
1652            }
1653        case OMX_QcomIndexParamH264AUDelimiter:
1654            {
1655                OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
1656                    (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
1657
1658                DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
1659                if(venc_set_au_delimiter(pParam->bEnable) == false) {
1660                    DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
1661                    return OMX_ErrorUnsupportedSetting;
1662                }
1663
1664                break;
1665            }
1666         case OMX_QcomIndexHierarchicalStructure:
1667           {
1668               QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
1669                   (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
1670
1671                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1672                    if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
1673                        DEBUG_PRINT_ERROR("Setting Hier P count failed");
1674                        return false;
1675                    }
1676                } else {
1677                    DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
1678                    return false;
1679                }
1680
1681                // For VP8, hier-p and ltr are mutually exclusive features in firmware
1682                // Disable ltr if hier-p is enabled.
1683                if (m_codec == OMX_VIDEO_CodingVP8) {
1684                    DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
1685                    if(!venc_set_ltrmode(0, 1)) {
1686                         DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
1687                     }
1688                }
1689                break;
1690           }
1691        case OMX_QcomIndexParamPerfLevel:
1692            {
1693                OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
1694                        (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
1695                DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
1696                if(!venc_set_perf_level(pParam->ePerfLevel)) {
1697                    DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
1698                    return false;
1699                } else {
1700                    performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
1701                }
1702                break;
1703            }
1704        case OMX_QcomIndexParamH264VUITimingInfo:
1705            {
1706                OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1707                        (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1708                DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1709                if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1710                    DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1711                    return false;
1712                } else {
1713                    vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1714                }
1715                break;
1716            }
1717        case OMX_QcomIndexParamPeakBitrate:
1718            {
1719                OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
1720                        (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
1721                DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
1722                if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
1723                    DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
1724                    return false;
1725                } else {
1726                    peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
1727                }
1728                break;
1729            }
1730       case OMX_QcomIndexParamSetMVSearchrange:
1731            {
1732               DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
1733               is_searchrange_set = true;
1734               if (!venc_set_searchrange()) {
1735                   DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1736                   return false;
1737               }
1738            }
1739            break;
1740        case OMX_IndexParamVideoSliceFMO:
1741        default:
1742            DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1743                    index);
1744            break;
1745            //case
1746    }
1747
1748    return true;
1749}
1750
1751bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1752{
1753
1754    DEBUG_PRINT_LOW("Inside venc_set_config");
1755
1756    switch ((int)index) {
1757        case OMX_IndexConfigVideoBitrate:
1758            {
1759                OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1760                    configData;
1761                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
1762
1763                if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1764                    if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1765                        DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
1766                        return false;
1767                    }
1768                } else {
1769                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1770                }
1771
1772                break;
1773            }
1774        case OMX_IndexConfigVideoFramerate:
1775            {
1776                OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1777                    configData;
1778                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
1779
1780                if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1781                    if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1782                        DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1783                        return false;
1784                    }
1785                } else {
1786                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1787                }
1788
1789                break;
1790            }
1791        case QOMX_IndexConfigVideoIntraperiod:
1792            {
1793                DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
1794                QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1795                    (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1796
1797                if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1798                    if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1799                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1800                        return false;
1801                    }
1802                }
1803
1804                break;
1805            }
1806        case OMX_IndexConfigVideoIntraVOPRefresh:
1807            {
1808                OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1809                    configData;
1810                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1811
1812                if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1813                    if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
1814                        DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1815                        return false;
1816                    }
1817                } else {
1818                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1819                }
1820
1821                break;
1822            }
1823        case OMX_IndexConfigCommonRotate:
1824            {
1825                OMX_CONFIG_ROTATIONTYPE *config_rotation =
1826                    reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1827                OMX_U32 nFrameWidth;
1828                if (true == deinterlace_enabled) {
1829                    DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
1830                    return false;
1831                }
1832                DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
1833                nFrameWidth = m_sVenc_cfg.dvs_width;
1834                m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
1835                m_sVenc_cfg.dvs_height = nFrameWidth;
1836
1837                if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
1838                    DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
1839                    return false;
1840                }
1841
1842                break;
1843            }
1844        case OMX_IndexConfigVideoAVCIntraPeriod:
1845            {
1846                OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
1847                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
1848
1849                if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
1850                        == false) {
1851                    DEBUG_PRINT_ERROR("ERROR: Setting "
1852                            "OMX_IndexConfigVideoAVCIntraPeriod failed");
1853                    return false;
1854                }
1855                break;
1856            }
1857        case OMX_IndexConfigCommonDeinterlace:
1858            {
1859                OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
1860                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
1861                if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1862                    if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
1863                        m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
1864                    {
1865                        DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
1866                        return false;
1867                    }
1868                    if(venc_set_deinterlace(deinterlace->nEnable) == false) {
1869                        DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
1870                        return false;
1871                    }
1872                } else {
1873                DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
1874                }
1875                break;
1876            }
1877       case OMX_IndexConfigVideoVp8ReferenceFrame:
1878           {
1879               OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
1880                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
1881                if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
1882                    (vp8refframe->bUseGoldenFrame)) {
1883                    if(venc_set_useltr() == false) {
1884                        DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
1885                        return false;
1886                    }
1887                } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
1888                    (vp8refframe->bGoldenFrameRefresh)) {
1889                    if(venc_set_markltr() == false) {
1890                        DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
1891                        return false;
1892                    }
1893                } else {
1894                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
1895                }
1896                break;
1897            }
1898        default:
1899            DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
1900            break;
1901    }
1902
1903    return true;
1904}
1905
1906unsigned venc_dev::venc_stop( void)
1907{
1908    struct venc_msg venc_msg;
1909    struct v4l2_requestbuffers bufreq;
1910    int rc = 0, ret = 0;
1911
1912    if (!stopped) {
1913        enum v4l2_buf_type cap_type;
1914
1915        if (streaming[OUTPUT_PORT]) {
1916            cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1917            rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1918
1919            if (rc) {
1920                DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
1921                        cap_type, rc);
1922            } else
1923                streaming[OUTPUT_PORT] = false;
1924
1925            DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
1926            bufreq.memory = V4L2_MEMORY_USERPTR;
1927            bufreq.count = 0;
1928            bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1929            ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1930
1931            if (ret) {
1932                DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
1933                return false;
1934            }
1935        }
1936
1937        if (!rc && streaming[CAPTURE_PORT]) {
1938            cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1939            rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1940
1941            if (rc) {
1942                DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
1943                        cap_type, rc);
1944            } else
1945                streaming[CAPTURE_PORT] = false;
1946
1947            DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
1948            bufreq.memory = V4L2_MEMORY_USERPTR;
1949            bufreq.count = 0;
1950            bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1951            ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1952
1953            if (ret) {
1954                DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
1955                return false;
1956            }
1957        }
1958
1959        if (!rc && !ret) {
1960            venc_stop_done();
1961            stopped = 1;
1962            /*set flag to re-configure when started again*/
1963            resume_in_stopped = 1;
1964
1965        }
1966    }
1967
1968    return rc;
1969}
1970
1971unsigned venc_dev::venc_pause(void)
1972{
1973    pthread_mutex_lock(&pause_resume_mlock);
1974    paused = true;
1975    pthread_mutex_unlock(&pause_resume_mlock);
1976    return 0;
1977}
1978
1979unsigned venc_dev::venc_resume(void)
1980{
1981    pthread_mutex_lock(&pause_resume_mlock);
1982    paused = false;
1983    pthread_mutex_unlock(&pause_resume_mlock);
1984
1985    return pthread_cond_signal(&pause_resume_cond);
1986}
1987
1988unsigned venc_dev::venc_start_done(void)
1989{
1990    struct venc_msg venc_msg;
1991    venc_msg.msgcode = VEN_MSG_START;
1992    venc_msg.statuscode = VEN_S_SUCCESS;
1993    venc_handle->async_message_process(venc_handle,&venc_msg);
1994    return 0;
1995}
1996
1997unsigned venc_dev::venc_stop_done(void)
1998{
1999    struct venc_msg venc_msg;
2000    free_extradata();
2001    venc_msg.msgcode=VEN_MSG_STOP;
2002    venc_msg.statuscode=VEN_S_SUCCESS;
2003    venc_handle->async_message_process(venc_handle,&venc_msg);
2004    return 0;
2005}
2006
2007unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2008{
2009    async_thread_created = true;
2010    m_tid=tid;
2011    return 0;
2012}
2013
2014
2015unsigned venc_dev::venc_start(void)
2016{
2017    enum v4l2_buf_type buf_type;
2018    int ret, r;
2019    struct v4l2_control control;
2020
2021    memset(&control, 0, sizeof(control));
2022
2023    DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2024            __func__);
2025
2026    if (!venc_set_profile_level(0, 0)) {
2027        DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2028                __func__);
2029    } else {
2030        DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2031                __func__, codec_profile.profile, profile_level.level);
2032    }
2033
2034    venc_config_print();
2035
2036    if(resume_in_stopped){
2037        /*set buffercount when restarted*/
2038        venc_reconfig_reqbufs();
2039        resume_in_stopped = 0;
2040    }
2041
2042    /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
2043    if (slice_mode.enable && multislice.mslice_size &&
2044            (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
2045        DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
2046                (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
2047                MAX_SUPPORTED_SLICES_PER_FRAME);
2048        return 1;
2049    }
2050
2051    buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2052    DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2053    ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
2054
2055    if (ret)
2056        return 1;
2057
2058    streaming[CAPTURE_PORT] = true;
2059
2060    control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
2061    control.value = 1;
2062    ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2063    if (ret) {
2064        DEBUG_PRINT_ERROR("failed to request seq header");
2065        return 1;
2066    }
2067
2068    stopped = 0;
2069    return 0;
2070}
2071
2072void venc_dev::venc_config_print()
2073{
2074
2075    DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
2076            m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
2077
2078    DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
2079            m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
2080            m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2081
2082    DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
2083            m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
2084            m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2085
2086    DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld",
2087            bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
2088
2089    DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
2090            session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
2091
2092    DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2093            init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2094
2095    DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2096            init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2097
2098    DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
2099            session_qp_values.minqp, session_qp_values.maxqp);
2100
2101    DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
2102            voptimecfg.voptime_resolution, multislice.mslice_mode,
2103            multislice.mslice_size);
2104
2105    DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
2106            entropy.longentropysel, entropy.cabacmodel);
2107
2108    DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
2109            dbkfilter.db_mode, dbkfilter.slicealpha_offset,
2110            dbkfilter.slicebeta_offset);
2111
2112    DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
2113            intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
2114
2115    DEBUG_PRINT_HIGH("ENC_CONFIG: Hier-P layers: %d", hier_p_layers.numlayers);
2116
2117    DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
2118
2119    DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
2120
2121    DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
2122}
2123
2124bool venc_dev::venc_reconfig_reqbufs()
2125{
2126    struct v4l2_requestbuffers bufreq;
2127
2128    bufreq.memory = V4L2_MEMORY_USERPTR;
2129    bufreq.count = m_sInput_buff_property.actualcount;
2130    bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2131    if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2132            DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
2133            return false;
2134    }
2135
2136    bufreq.memory = V4L2_MEMORY_USERPTR;
2137    bufreq.count = m_sOutput_buff_property.actualcount;
2138    bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2139    if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
2140    {
2141            DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
2142            return false;
2143    }
2144    return true;
2145}
2146
2147unsigned venc_dev::venc_flush( unsigned port)
2148{
2149    struct v4l2_encoder_cmd enc;
2150    DEBUG_PRINT_LOW("in %s", __func__);
2151
2152    enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
2153    enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
2154
2155    if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
2156        DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
2157        return -1;
2158    }
2159
2160    return 0;
2161
2162}
2163
2164//allocating I/P memory from pmem and register with the device
2165
2166
2167bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
2168{
2169
2170    struct pmem *pmem_tmp;
2171    struct v4l2_buffer buf;
2172    struct v4l2_plane plane[VIDEO_MAX_PLANES];
2173    int rc = 0, extra_idx;
2174
2175    pmem_tmp = (struct pmem *)buf_addr;
2176    DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
2177
2178    if (port == PORT_INDEX_IN) {
2179        buf.index = index;
2180        buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2181        buf.memory = V4L2_MEMORY_USERPTR;
2182        plane[0].length = pmem_tmp->size;
2183        plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2184        plane[0].reserved[0] = pmem_tmp->fd;
2185        plane[0].reserved[1] = 0;
2186        plane[0].data_offset = pmem_tmp->offset;
2187        buf.m.planes = plane;
2188        buf.length = 1;
2189
2190        rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2191
2192        if (rc)
2193            DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2194    } else if (port == PORT_INDEX_OUT) {
2195        extra_idx = EXTRADATA_IDX(num_planes);
2196
2197        if ((num_planes > 1) && (extra_idx)) {
2198            rc = allocate_extradata();
2199
2200            if (rc)
2201                DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc);
2202        }
2203
2204        buf.index = index;
2205        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2206        buf.memory = V4L2_MEMORY_USERPTR;
2207        plane[0].length = pmem_tmp->size;
2208        plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2209        plane[0].reserved[0] = pmem_tmp->fd;
2210        plane[0].reserved[1] = 0;
2211        plane[0].data_offset = pmem_tmp->offset;
2212        buf.m.planes = plane;
2213        buf.length = num_planes;
2214
2215        if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2216            plane[extra_idx].length = extradata_info.buffer_size;
2217            plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2218#ifdef USE_ION
2219            plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2220#endif
2221            plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2222            plane[extra_idx].data_offset = 0;
2223        } else if  (extra_idx >= VIDEO_MAX_PLANES) {
2224            DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
2225            return OMX_ErrorBadParameter;
2226        }
2227
2228        rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2229
2230        if (rc)
2231            DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2232    } else {
2233        DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
2234        return false;
2235    }
2236
2237    return true;
2238}
2239
2240bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
2241{
2242    struct pmem *pmem_tmp;
2243    struct venc_bufferpayload dev_buffer;
2244
2245    memset(&dev_buffer, 0, sizeof(dev_buffer));
2246    pmem_tmp = (struct pmem *)buf_addr;
2247
2248    if (port == PORT_INDEX_IN) {
2249        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2250        dev_buffer.fd  = pmem_tmp->fd;
2251        dev_buffer.maped_size = pmem_tmp->size;
2252        dev_buffer.sz = pmem_tmp->size;
2253        dev_buffer.offset = pmem_tmp->offset;
2254        DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2255                dev_buffer.pbuffer, \
2256                dev_buffer.fd, \
2257                dev_buffer.offset, \
2258                dev_buffer.maped_size);
2259
2260    } else if (port == PORT_INDEX_OUT) {
2261        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2262        dev_buffer.fd  = pmem_tmp->fd;
2263        dev_buffer.sz = pmem_tmp->size;
2264        dev_buffer.maped_size = pmem_tmp->size;
2265        dev_buffer.offset = pmem_tmp->offset;
2266
2267        DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2268                dev_buffer.pbuffer, \
2269                dev_buffer.fd, \
2270                dev_buffer.offset, \
2271                dev_buffer.maped_size);
2272    } else {
2273        DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
2274        return false;
2275    }
2276
2277    return true;
2278}
2279
2280bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
2281        OMX_U32 width, OMX_U32 height)
2282{
2283    OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2284            y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2285            uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2286            uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2287            src_chroma_offset = width * height;
2288
2289    if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2290        OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2291        //Do chroma first, so that we can convert it in-place
2292        src_buf += width * height;
2293        dst_buf += y_stride * y_scanlines;
2294        for (int line = height / 2 - 1; line >= 0; --line) {
2295            memmove(dst_buf + line * uv_stride,
2296                    src_buf + line * width,
2297                    width);
2298        }
2299
2300        dst_buf = src_buf = buffer->pBuffer;
2301        //Copy the Y next
2302        for (int line = height - 1; line > 0; --line) {
2303            memmove(dst_buf + line * y_stride,
2304                    src_buf + line * width,
2305                    width);
2306        }
2307    } else {
2308        DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
2309                Insufficient bufferLen=%u v/s Required=%u",
2310                (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
2311                VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
2312        return false;
2313    }
2314
2315    return true;
2316}
2317
2318bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
2319{
2320    if (!perflevel) {
2321        DEBUG_PRINT_ERROR("Null pointer error");
2322        return false;
2323    } else {
2324        *perflevel = performance_level.perflevel;
2325        return true;
2326    }
2327}
2328
2329bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
2330{
2331    if (!enabled) {
2332        DEBUG_PRINT_ERROR("Null pointer error");
2333        return false;
2334    } else {
2335        *enabled = vui_timing_info.enabled;
2336        return true;
2337    }
2338}
2339
2340bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
2341{
2342    if (!peakbitrate) {
2343        DEBUG_PRINT_ERROR("Null pointer error");
2344        return false;
2345    } else {
2346        *peakbitrate = peak_bitrate.peakbitrate;
2347        return true;
2348    }
2349}
2350
2351bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
2352{
2353    struct pmem *temp_buffer;
2354    struct v4l2_buffer buf;
2355    struct v4l2_plane plane;
2356    int rc=0;
2357    struct OMX_BUFFERHEADERTYPE *bufhdr;
2358    encoder_media_buffer_type * meta_buf = NULL;
2359    temp_buffer = (struct pmem *)buffer;
2360
2361    memset (&buf, 0, sizeof(buf));
2362    memset (&plane, 0, sizeof(plane));
2363
2364    if (buffer == NULL) {
2365        DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
2366        return false;
2367    }
2368
2369    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2370
2371    DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
2372
2373    if (pmem_data_buf) {
2374        DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
2375        plane.m.userptr = (unsigned long)pmem_data_buf;
2376        plane.data_offset = bufhdr->nOffset;
2377        plane.length = bufhdr->nAllocLen;
2378        plane.bytesused = bufhdr->nFilledLen;
2379    } else {
2380        // --------------------------------------------------------------------------------------
2381        // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
2382        // ---------------------------------------------------------------------------------------
2383        // Camera-2              1            CameraSource   0              meta-handle
2384        // Camera-3              1            GrallocSource  0              gralloc-private-handle
2385        // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
2386        // CPU (Eg: MediaCodec)  0            --             0              bufhdr
2387        // ---------------------------------------------------------------------------------------
2388        if (metadatamode) {
2389            plane.m.userptr = index;
2390            meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
2391
2392            if (!meta_buf) {
2393                //empty EOS buffer
2394                if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
2395                    plane.data_offset = bufhdr->nOffset;
2396                    plane.length = bufhdr->nAllocLen;
2397                    plane.bytesused = bufhdr->nFilledLen;
2398                    DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
2399                } else {
2400                    return false;
2401                }
2402            } else if (!color_format) {
2403                if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
2404                    if (meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709)
2405                        buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2406                    plane.data_offset = meta_buf->meta_handle->data[1];
2407                    plane.length = meta_buf->meta_handle->data[2];
2408                    plane.bytesused = meta_buf->meta_handle->data[2];
2409                    DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
2410                            fd, plane.bytesused, plane.length, buf.flags);
2411                } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
2412                    private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
2413                    fd = handle->fd;
2414                    plane.data_offset = 0;
2415                    plane.length = handle->size;
2416                    plane.bytesused = handle->size;
2417                        DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
2418                                ": filled %d of %d", fd, plane.bytesused, plane.length);
2419                }
2420            } else {
2421                plane.data_offset = bufhdr->nOffset;
2422                plane.length = bufhdr->nAllocLen;
2423                plane.bytesused = bufhdr->nFilledLen;
2424                DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
2425                        ": filled %d of %d", fd, plane.bytesused, plane.length);
2426            }
2427        } else {
2428            plane.data_offset = bufhdr->nOffset;
2429            plane.length = bufhdr->nAllocLen;
2430            plane.bytesused = bufhdr->nFilledLen;
2431            DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
2432                    fd, plane.bytesused, plane.length);
2433        }
2434    }
2435
2436    buf.index = index;
2437    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2438    buf.memory = V4L2_MEMORY_USERPTR;
2439    plane.reserved[0] = fd;
2440    plane.reserved[1] = 0;
2441    buf.m.planes = &plane;
2442    buf.length = 1;
2443
2444    if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2445        buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
2446
2447    buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
2448    buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
2449    rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2450
2451    if (rc) {
2452        DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
2453        return false;
2454    }
2455
2456    etb++;
2457
2458    if (!streaming[OUTPUT_PORT]) {
2459        enum v4l2_buf_type buf_type;
2460        buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2461        int ret;
2462        ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
2463
2464        if (ret) {
2465            DEBUG_PRINT_ERROR("Failed to call streamon");
2466            return false;
2467        } else {
2468            streaming[OUTPUT_PORT] = true;
2469        }
2470    }
2471    if (m_debug.in_buffer_log) {
2472        venc_input_log_buffers(bufhdr, fd, plane.data_offset);
2473    }
2474
2475    return true;
2476}
2477bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
2478{
2479    struct pmem *temp_buffer = NULL;
2480    struct venc_buffer  frameinfo;
2481    struct v4l2_buffer buf;
2482    struct v4l2_plane plane[VIDEO_MAX_PLANES];
2483    int rc = 0, extra_idx;
2484    struct OMX_BUFFERHEADERTYPE *bufhdr;
2485
2486    if (buffer == NULL)
2487        return false;
2488
2489    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2490
2491    if (pmem_data_buf) {
2492        DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
2493        plane[0].m.userptr = (unsigned long)pmem_data_buf;
2494    } else {
2495        DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
2496        plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
2497    }
2498
2499    buf.index = index;
2500    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2501    buf.memory = V4L2_MEMORY_USERPTR;
2502    plane[0].length = bufhdr->nAllocLen;
2503    plane[0].bytesused = bufhdr->nFilledLen;
2504    plane[0].reserved[0] = fd;
2505    plane[0].reserved[1] = 0;
2506    plane[0].data_offset = bufhdr->nOffset;
2507    buf.m.planes = plane;
2508    buf.length = num_planes;
2509
2510    extra_idx = EXTRADATA_IDX(num_planes);
2511
2512    if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2513        plane[extra_idx].bytesused = 0;
2514        plane[extra_idx].length = extradata_info.buffer_size;
2515        plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2516#ifdef USE_ION
2517        plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2518#endif
2519        plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2520        plane[extra_idx].data_offset = 0;
2521    } else if (extra_idx >= VIDEO_MAX_PLANES) {
2522        DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
2523        return false;
2524    }
2525
2526    rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2527
2528    if (rc) {
2529        DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
2530        return false;
2531    }
2532
2533    ftb++;
2534    return true;
2535}
2536
2537bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
2538{
2539    struct v4l2_control control;
2540
2541    control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
2542    if(enable) {
2543        control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
2544    } else {
2545        control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
2546    }
2547
2548    DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
2549    if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2550        DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
2551        return false;
2552    }
2553    return true;
2554}
2555
2556bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
2557{
2558    struct v4l2_control control;
2559
2560    control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
2561    if(enable) {
2562        control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
2563    } else {
2564        control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
2565    }
2566
2567    DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
2568    if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2569        DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
2570        return false;
2571    }
2572    return true;
2573}
2574
2575bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
2576                                    OMX_U32 num_layers)
2577{
2578    struct v4l2_control control;
2579    control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
2580    if (type == QOMX_HIERARCHICALCODING_P) {
2581        control.value = num_layers;
2582        DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
2583        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2584            DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
2585            return false;
2586        }
2587        hier_p_layers.numlayers = num_layers;
2588    } else {
2589        DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
2590        return false;
2591    }
2592    return true;
2593}
2594
2595bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
2596{
2597    struct v4l2_control control;
2598
2599    DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
2600
2601    if (enable == OMX_FALSE) {
2602        /* No easy way to turn off extradata to the driver
2603         * at the moment */
2604        return false;
2605    }
2606
2607    control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2608    switch (extra_data) {
2609        case OMX_ExtraDataVideoEncoderSliceInfo:
2610            control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
2611            break;
2612        case OMX_ExtraDataVideoEncoderMBInfo:
2613            control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
2614            break;
2615        default:
2616            DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
2617            return false;
2618    }
2619
2620    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2621        DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
2622                (unsigned int)extra_data, errno);
2623        return false;
2624    }
2625
2626    return true;
2627}
2628
2629bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
2630{
2631    struct v4l2_control control;
2632
2633    if (enable) {
2634        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
2635        control.value = 1;
2636        DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
2637
2638        if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2639            if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2640                DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
2641                return false;
2642            } else {
2643                DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
2644                slice_mode.enable = 1;
2645            }
2646        } else {
2647            DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
2648                    "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
2649                    m_sVenc_cfg.codectype);
2650        }
2651    } else {
2652        DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
2653    }
2654
2655    return true;
2656}
2657
2658bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
2659{
2660    int rc;
2661    struct v4l2_control control;
2662    struct v4l2_ext_control ctrl[4];
2663    struct v4l2_ext_controls controls;
2664
2665    ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
2666    ctrl[0].value = initqp->nQpI;
2667    ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
2668    ctrl[1].value = initqp->nQpP;
2669    ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
2670    ctrl[2].value = initqp->nQpB;
2671    ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
2672    ctrl[3].value = initqp->bEnableInitQp;
2673
2674    controls.count = 4;
2675    controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
2676    controls.controls = ctrl;
2677
2678    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
2679                    controls.controls[0].id, controls.controls[0].value,
2680                    controls.controls[1].id, controls.controls[1].value,
2681                    controls.controls[2].id, controls.controls[2].value,
2682                    controls.controls[3].id, controls.controls[3].value);
2683
2684    rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
2685    if (rc) {
2686        DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
2687        return false;
2688    }
2689
2690    init_qp.iframeqp = initqp->nQpI;
2691    init_qp.pframeqp = initqp->nQpP;
2692    init_qp.bframeqp = initqp->nQpB;
2693    init_qp.enableinitqp = initqp->bEnableInitQp;
2694
2695    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
2696                    controls.controls[0].id, controls.controls[0].value,
2697                    controls.controls[1].id, controls.controls[1].value,
2698                    controls.controls[2].id, controls.controls[2].value,
2699                    controls.controls[3].id, controls.controls[3].value);
2700    return true;
2701}
2702
2703bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
2704{
2705    int rc;
2706    struct v4l2_control control;
2707
2708    control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
2709    control.value = i_frame_qp;
2710
2711    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2712    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2713
2714    if (rc) {
2715        DEBUG_PRINT_ERROR("Failed to set control");
2716        return false;
2717    }
2718
2719    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2720    session_qp.iframeqp = control.value;
2721
2722    control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
2723    control.value = p_frame_qp;
2724
2725    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2726    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2727
2728    if (rc) {
2729        DEBUG_PRINT_ERROR("Failed to set control");
2730        return false;
2731    }
2732
2733    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2734
2735    session_qp.pframeqp = control.value;
2736
2737    if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
2738            (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
2739
2740        control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
2741        control.value = b_frame_qp;
2742
2743        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2744        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2745
2746        if (rc) {
2747            DEBUG_PRINT_ERROR("Failed to set control");
2748            return false;
2749        }
2750
2751        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2752
2753        session_qp.bframeqp = control.value;
2754    }
2755
2756    return true;
2757}
2758
2759bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
2760{
2761    int rc;
2762    struct v4l2_control control;
2763
2764    if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
2765
2766        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
2767            control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
2768        else
2769            control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
2770        control.value = min_qp;
2771
2772        DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
2773                control.id, control.value);
2774        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2775        if (rc) {
2776            DEBUG_PRINT_ERROR("Failed to set control\n");
2777            return false;
2778        }
2779
2780        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
2781            control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
2782        else
2783            control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
2784        control.value = max_qp;
2785
2786        DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
2787                control.id, control.value);
2788        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2789        if (rc) {
2790            DEBUG_PRINT_ERROR("Failed to set control\n");
2791            return false;
2792        }
2793    } else {
2794        DEBUG_PRINT_ERROR("Wrong qp values[%lu %lu], allowed range[%lu %lu]",
2795            min_qp, max_qp, session_qp_range.minqp, session_qp_range.maxqp);
2796    }
2797
2798    return true;
2799}
2800
2801bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
2802{
2803    struct venc_profile requested_profile = {0};
2804    struct ven_profilelevel requested_level = {0};
2805    unsigned long mb_per_frame = 0;
2806    DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
2807            (unsigned int)eProfile, (unsigned int)eLevel);
2808    mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
2809        ((m_sVenc_cfg.dvs_width + 15) >> 4);
2810
2811    if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
2812        DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
2813        return true;
2814    }
2815
2816    DEBUG_PRINT_LOW("Validating Profile/Level from table");
2817
2818    if (!venc_validate_profile_level(&eProfile, &eLevel)) {
2819        DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
2820        return false;
2821    }
2822
2823    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2824        DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
2825                "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
2826                OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
2827
2828        if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
2829            requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
2830        } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
2831            requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
2832        } else {
2833            DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
2834                    (unsigned int)eProfile);
2835            return false;
2836        }
2837
2838        DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
2839                "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
2840                "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
2841                OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
2842
2843        if (mb_per_frame >= 3600) {
2844            if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
2845                requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2846
2847            if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
2848                requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2849        } else {
2850            switch (eLevel) {
2851                case OMX_VIDEO_MPEG4Level0:
2852                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
2853                    break;
2854                case OMX_VIDEO_MPEG4Level0b:
2855                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
2856                    break;
2857                case OMX_VIDEO_MPEG4Level1:
2858                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
2859                    break;
2860                case OMX_VIDEO_MPEG4Level2:
2861                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
2862                    break;
2863                case OMX_VIDEO_MPEG4Level3:
2864                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
2865                    break;
2866                case OMX_VIDEO_MPEG4Level4a:
2867                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
2868                    break;
2869                case OMX_VIDEO_MPEG4Level5:
2870                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2871                    break;
2872                default:
2873                    return false;
2874                    // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
2875                    break;
2876            }
2877        }
2878    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
2879
2880        switch (eProfile) {
2881            case OMX_VIDEO_H263ProfileBaseline:
2882                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
2883                break;
2884            case OMX_VIDEO_H263ProfileH320Coding:
2885                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
2886                break;
2887            case OMX_VIDEO_H263ProfileBackwardCompatible:
2888                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
2889                break;
2890            case OMX_VIDEO_H263ProfileISWV2:
2891                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
2892                break;
2893            case OMX_VIDEO_H263ProfileISWV3:
2894                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
2895                break;
2896            case OMX_VIDEO_H263ProfileHighCompression:
2897                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
2898                break;
2899            case OMX_VIDEO_H263ProfileInternet:
2900                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
2901                break;
2902            case OMX_VIDEO_H263ProfileInterlace:
2903                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
2904                break;
2905            case OMX_VIDEO_H263ProfileHighLatency:
2906                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
2907                break;
2908            default:
2909                DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
2910                        requested_profile.profile);
2911                return false;
2912        }
2913
2914        //profile level
2915        switch (eLevel) {
2916            case OMX_VIDEO_H263Level10:
2917                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
2918                break;
2919            case OMX_VIDEO_H263Level20:
2920                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
2921                break;
2922            case OMX_VIDEO_H263Level30:
2923                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
2924                break;
2925            case OMX_VIDEO_H263Level40:
2926                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
2927                break;
2928            case OMX_VIDEO_H263Level45:
2929                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
2930                break;
2931            case OMX_VIDEO_H263Level50:
2932                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
2933                break;
2934            case OMX_VIDEO_H263Level60:
2935                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
2936                break;
2937            case OMX_VIDEO_H263Level70:
2938                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
2939                break;
2940            default:
2941                return false;
2942                break;
2943        }
2944    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2945        if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
2946            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
2947        } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
2948            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
2949        } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
2950            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
2951        } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
2952            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
2953        } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
2954            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
2955        } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
2956            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
2957        } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
2958            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
2959        } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
2960            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
2961        } else {
2962            DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
2963                    requested_profile.profile);
2964            return false;
2965        }
2966
2967        //profile level
2968        switch (eLevel) {
2969            case OMX_VIDEO_AVCLevel1:
2970                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
2971                break;
2972            case OMX_VIDEO_AVCLevel1b:
2973                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
2974                break;
2975            case OMX_VIDEO_AVCLevel11:
2976                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
2977                break;
2978            case OMX_VIDEO_AVCLevel12:
2979                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
2980                break;
2981            case OMX_VIDEO_AVCLevel13:
2982                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
2983                break;
2984            case OMX_VIDEO_AVCLevel2:
2985                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
2986                break;
2987            case OMX_VIDEO_AVCLevel21:
2988                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
2989                break;
2990            case OMX_VIDEO_AVCLevel22:
2991                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
2992                break;
2993            case OMX_VIDEO_AVCLevel3:
2994                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
2995                break;
2996            case OMX_VIDEO_AVCLevel31:
2997                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
2998                break;
2999            case OMX_VIDEO_AVCLevel32:
3000                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
3001                break;
3002            case OMX_VIDEO_AVCLevel4:
3003                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
3004                break;
3005            case OMX_VIDEO_AVCLevel41:
3006                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
3007                break;
3008            case OMX_VIDEO_AVCLevel42:
3009                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
3010                break;
3011            case OMX_VIDEO_AVCLevel5:
3012                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
3013                break;
3014            case OMX_VIDEO_AVCLevel51:
3015                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
3016                break;
3017            case OMX_VIDEO_AVCLevel52:
3018                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3019                break;
3020            case OMX_VIDEO_AVCLevelMax:
3021                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3022                break;
3023            default :
3024                DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
3025                        requested_level.level);
3026                return false;
3027                break;
3028        }
3029    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3030        if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
3031            DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
3032                        (unsigned int)eProfile);
3033            return false;
3034        }
3035        requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
3036        m_profile_set = true;
3037        switch(eLevel) {
3038            case OMX_VIDEO_VP8Level_Version0:
3039                requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
3040                break;
3041            case OMX_VIDEO_VP8Level_Version1:
3042                requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
3043                break;
3044            default:
3045                DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
3046                            (unsigned int)eLevel);
3047                return false;
3048                break;
3049        }
3050    }
3051
3052    if (!m_profile_set) {
3053        int rc;
3054        struct v4l2_control control;
3055
3056        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3057            control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3058        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3059            control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
3060        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3061            control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
3062        } else {
3063            DEBUG_PRINT_ERROR("Wrong CODEC");
3064            return false;
3065        }
3066
3067        control.value = requested_profile.profile;
3068
3069        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3070        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3071
3072        if (rc) {
3073            DEBUG_PRINT_ERROR("Failed to set control");
3074            return false;
3075        }
3076
3077        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3078
3079        codec_profile.profile = control.value;
3080        m_profile_set = true;
3081    }
3082
3083    if (!m_level_set) {
3084        int rc;
3085        struct v4l2_control control;
3086
3087        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3088            control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3089        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3090            control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
3091        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3092            control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
3093        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3094            control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3095        } else {
3096            DEBUG_PRINT_ERROR("Wrong CODEC");
3097            return false;
3098        }
3099
3100        control.value = requested_level.level;
3101
3102        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3103        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3104
3105        if (rc) {
3106            DEBUG_PRINT_ERROR("Failed to set control");
3107            return false;
3108        }
3109
3110        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3111
3112        profile_level.level = control.value;
3113        m_level_set = true;
3114    }
3115
3116    return true;
3117}
3118
3119bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
3120{
3121
3122    struct venc_voptimingcfg vop_timing_cfg;
3123
3124    DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
3125            (unsigned int)TimeIncRes);
3126
3127    vop_timing_cfg.voptime_resolution = TimeIncRes;
3128
3129    voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
3130    return true;
3131}
3132
3133bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
3134{
3135
3136    DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
3137    int rc;
3138    struct v4l2_control control;
3139    int pframe = 0, bframe = 0;
3140
3141    if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
3142            (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
3143            (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3144        nBFrames=0;
3145    }
3146    if ((display_info.w * display_info.h > OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
3147        && enable_mv_narrow_searchrange && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >=
3148        OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT || is_searchrange_set)) {
3149        nBFrames=0;
3150    }
3151
3152    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
3153    control.value = nPFrames;
3154    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3155
3156    if (rc) {
3157        DEBUG_PRINT_ERROR("Failed to set control");
3158        return false;
3159    }
3160
3161    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3162
3163    intra_period.num_pframes = control.value;
3164    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
3165    control.value = nBFrames;
3166    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3167    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3168
3169    if (rc) {
3170        DEBUG_PRINT_ERROR("Failed to set control");
3171        return false;
3172    }
3173
3174    intra_period.num_bframes = nBFrames;
3175    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
3176
3177    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3178        control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3179        control.value = 1;
3180
3181        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3182
3183        if (rc) {
3184            DEBUG_PRINT_ERROR("Failed to set control");
3185            return false;
3186        }
3187
3188        idrperiod.idrperiod = 1;
3189    }
3190
3191    return true;
3192}
3193
3194bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
3195{
3196    int rc = 0;
3197    struct v4l2_control control;
3198    DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
3199            (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
3200
3201    if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
3202        DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
3203        return false;
3204    }
3205
3206    if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
3207        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
3208        return false;
3209    }
3210
3211    if (!intra_period.num_bframes)
3212    intra_period.num_pframes = nPFrames;
3213    control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3214    control.value = nIDRPeriod;
3215
3216    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3217
3218    if (rc) {
3219        DEBUG_PRINT_ERROR("Failed to set control");
3220        return false;
3221    }
3222
3223    idrperiod.idrperiod = nIDRPeriod;
3224    return true;
3225}
3226
3227bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
3228{
3229    int rc = 0;
3230    struct v4l2_control control;
3231
3232    DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
3233
3234    if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
3235            (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
3236
3237        control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
3238        control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3239
3240        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3241        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3242
3243        if (rc) {
3244            DEBUG_PRINT_ERROR("Failed to set control");
3245            return false;
3246        }
3247
3248        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3249        entropy.longentropysel = control.value;
3250
3251        if (i_cabac_level == 0) {
3252            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
3253        } else if (i_cabac_level == 1) {
3254            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
3255        } else if (i_cabac_level == 2) {
3256            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
3257        }
3258
3259        control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
3260        //control.value = entropy_cfg.cabacmodel;
3261        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3262        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3263
3264        if (rc) {
3265            DEBUG_PRINT_ERROR("Failed to set control");
3266            return false;
3267        }
3268
3269        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3270        entropy.cabacmodel=control.value;
3271    } else if (!enable) {
3272        control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
3273        control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3274        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3275        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3276
3277        if (rc) {
3278            DEBUG_PRINT_ERROR("Failed to set control");
3279            return false;
3280        }
3281
3282        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3283        entropy.longentropysel=control.value;
3284    } else {
3285        DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
3286        return false;
3287    }
3288
3289    return true;
3290}
3291
3292bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
3293{
3294    int rc;
3295    struct v4l2_control control;
3296    bool status = true;
3297
3298    if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
3299        control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
3300    } else {
3301        control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3302    }
3303
3304    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3305    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3306    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3307
3308    if (rc) {
3309        DEBUG_PRINT_ERROR("Failed to set control");
3310        return false;
3311    }
3312
3313    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3314    multislice.mslice_mode=control.value;
3315
3316    if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
3317
3318        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
3319        control.value = nSlicesize;
3320        DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
3321        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3322
3323        if (rc) {
3324            DEBUG_PRINT_ERROR("Failed to set control");
3325            return false;
3326        }
3327
3328        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3329        multislice.mslice_size=control.value;
3330
3331    }
3332
3333    return status;
3334}
3335
3336bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
3337{
3338    bool status = true;
3339    int rc;
3340    struct v4l2_control control_mode,control_mbs;
3341    control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
3342
3343    // There is no disabled mode.  Disabled mode is indicated by a 0 count.
3344    if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
3345        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
3346        return status;
3347    } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
3348            (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3349        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
3350        control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
3351        control_mbs.value=irMBs;
3352    } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
3353            (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3354        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
3355        control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3356        control_mbs.value=irMBs;
3357    } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
3358            (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3359        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
3360    } else {
3361        DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
3362                "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
3363        return false;
3364    }
3365
3366    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
3367    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
3368
3369    if (rc) {
3370        DEBUG_PRINT_ERROR("Failed to set control");
3371        return false;
3372    }
3373
3374    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
3375
3376    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
3377    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
3378
3379    if (rc) {
3380        DEBUG_PRINT_ERROR("Failed to set control");
3381        return false;
3382    }
3383
3384    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
3385
3386    intra_refresh.irmode = control_mode.value;
3387    intra_refresh.mbcount = control_mbs.value;
3388
3389    return status;
3390}
3391
3392bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
3393{
3394    bool status = true;
3395    struct venc_headerextension hec_cfg;
3396    struct venc_multiclicecfg multislice_cfg;
3397    int rc;
3398    OMX_U32 resynchMarkerSpacingBytes = 0;
3399    struct v4l2_control control;
3400
3401    memset(&control, 0, sizeof(control));
3402
3403    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3404        if (error_resilience->bEnableHEC) {
3405            hec_cfg.header_extension = 1;
3406        } else {
3407            hec_cfg.header_extension = 0;
3408        }
3409
3410        hec.header_extension = error_resilience->bEnableHEC;
3411    }
3412
3413    if (error_resilience->bEnableRVLC) {
3414        DEBUG_PRINT_ERROR("RVLC is not Supported");
3415        return false;
3416    }
3417
3418    if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3419            (error_resilience->bEnableDataPartitioning)) {
3420        DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
3421        return false;
3422    }
3423
3424    if (error_resilience->nResynchMarkerSpacing) {
3425        resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
3426        resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
3427    }
3428    if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3429            (error_resilience->nResynchMarkerSpacing)) {
3430        multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
3431        multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3432        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3433        control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
3434    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
3435            error_resilience->bEnableDataPartitioning) {
3436        multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
3437        multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3438        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3439        control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
3440    } else {
3441        multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
3442        multislice_cfg.mslice_size = 0;
3443        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3444        control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3445    }
3446
3447    DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
3448            multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
3449    DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3450    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3451
3452    if (rc) {
3453       DEBUG_PRINT_ERROR("Failed to set Slice mode control");
3454        return false;
3455    }
3456
3457    DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3458    multislice.mslice_mode=control.value;
3459
3460    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
3461    control.value = resynchMarkerSpacingBytes;
3462    DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3463
3464    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3465
3466    if (rc) {
3467       DEBUG_PRINT_ERROR("Failed to set MAX MB control");
3468        return false;
3469    }
3470
3471    DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3472    multislice.mslice_mode = multislice_cfg.mslice_mode;
3473    multislice.mslice_size = multislice_cfg.mslice_size;
3474    return status;
3475}
3476
3477bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
3478{
3479    int rc;
3480    struct v4l2_control control;
3481    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
3482
3483    if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
3484        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
3485    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
3486        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
3487    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
3488        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
3489    }
3490
3491    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3492    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3493
3494    if (rc) {
3495        return false;
3496    }
3497
3498    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3499
3500    dbkfilter.db_mode=control.value;
3501
3502    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
3503    control.value=0;
3504
3505    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3506    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3507
3508    if (rc) {
3509        return false;
3510    }
3511
3512    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3513    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
3514    control.value=0;
3515    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3516    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3517
3518    if (rc) {
3519        return false;
3520    }
3521
3522    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3523
3524
3525    dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
3526    return true;
3527}
3528
3529bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
3530{
3531    DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
3532            (unsigned int)nTargetBitrate);
3533    struct v4l2_control control;
3534    int rc = 0;
3535    control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
3536    control.value = nTargetBitrate;
3537
3538    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3539    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3540
3541    if (rc) {
3542        DEBUG_PRINT_ERROR("Failed to set control");
3543        return false;
3544    }
3545
3546    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3547
3548
3549    m_sVenc_cfg.targetbitrate = control.value;
3550    bitrate.target_bitrate = control.value;
3551
3552    if (!config) {
3553        m_level_set = false;
3554
3555        if (venc_set_profile_level(0, 0)) {
3556            DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
3557        }
3558    }
3559
3560    return true;
3561}
3562
3563bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
3564{
3565    struct v4l2_streamparm parm;
3566    int rc = 0;
3567    struct venc_framerate frame_rate_cfg;
3568    Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
3569    parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3570    parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
3571    parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
3572
3573    if (frame_rate_cfg.fps_numerator > 0)
3574        rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
3575
3576    if (rc) {
3577        DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
3578        return false;
3579    }
3580
3581    m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
3582    m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
3583
3584    if (!config) {
3585        m_level_set = false;
3586
3587        if (venc_set_profile_level(0, 0)) {
3588            DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
3589        }
3590    }
3591
3592    return true;
3593}
3594
3595bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
3596{
3597    struct v4l2_format fmt;
3598    DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
3599
3600    if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar ||
3601            (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3602        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3603    } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) {
3604        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
3605    } else {
3606        DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
3607        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3608        DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
3609    }
3610
3611    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3612    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3613    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3614    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3615
3616    if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3617        DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
3618        return false;
3619    }
3620
3621    return true;
3622}
3623
3624bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
3625{
3626    DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
3627
3628    if (intra_vop_refresh == OMX_TRUE) {
3629        struct v4l2_control control;
3630        int rc;
3631        control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
3632        control.value = 1;
3633       DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3634        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3635
3636        if (rc) {
3637           DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
3638            return false;
3639        }
3640
3641       DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3642    } else {
3643        DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
3644    }
3645
3646    return true;
3647}
3648
3649bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
3650{
3651    DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
3652    struct v4l2_control control;
3653    int rc;
3654    control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
3655    if (enable)
3656        control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
3657    else
3658        control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
3659
3660    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3661    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3662    if (rc) {
3663        DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
3664        return false;
3665    }
3666    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3667    deinterlace_enabled = true;
3668    return true;
3669}
3670
3671bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
3672{
3673    DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
3674    struct v4l2_control control;
3675    struct v4l2_ext_control ctrl[2];
3676    struct v4l2_ext_controls controls;
3677    int rc;
3678
3679    ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
3680    if (enable)
3681        ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
3682    else
3683        ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
3684
3685    ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
3686    if (count)
3687        ctrl[1].value = count;
3688    else
3689        ctrl[1].value = 1;
3690
3691    controls.count = 2;
3692    controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3693    controls.controls = ctrl;
3694
3695    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
3696                    controls.controls[0].id, controls.controls[0].value,
3697                    controls.controls[1].id, controls.controls[1].value);
3698
3699    rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3700    if (rc) {
3701        DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
3702        return false;
3703    }
3704
3705    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
3706                    controls.controls[0].id, controls.controls[0].value,
3707                    controls.controls[1].id, controls.controls[1].value);
3708
3709    control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
3710    control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR;
3711
3712    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3713        DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
3714        return false;
3715    }
3716    return true;
3717}
3718
3719bool venc_dev::venc_set_useltr()
3720{
3721    DEBUG_PRINT_LOW("venc_use_goldenframe");
3722    int rc = true;
3723    struct v4l2_control control;
3724
3725    control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
3726    control.value = 1;
3727
3728    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3729    if (rc) {
3730        DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
3731        return false;
3732    }
3733
3734    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3735                    control.id, control.value);
3736    return true;
3737}
3738
3739bool venc_dev::venc_set_markltr()
3740{
3741    DEBUG_PRINT_LOW("venc_set_goldenframe");
3742    int rc = true;
3743    struct v4l2_control control;
3744
3745    control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
3746    control.value = 1;
3747
3748    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3749    if (rc) {
3750        DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
3751        return false;
3752    }
3753
3754    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3755                    control.id, control.value);
3756    return true;
3757}
3758
3759bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
3760{
3761    DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
3762    struct v4l2_control control;
3763    int rc;
3764    struct v4l2_format fmt;
3765    struct v4l2_requestbuffers bufreq;
3766
3767    control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
3768    if (rotation_angle == 0)
3769        control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
3770    else if (rotation_angle == 90)
3771        control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
3772    else if (rotation_angle == 180)
3773        control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
3774    else if (rotation_angle == 270)
3775        control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
3776    else {
3777        DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
3778        return false;
3779    }
3780
3781    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3782    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3783    if (rc) {
3784        DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
3785        return false;
3786    }
3787    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3788
3789    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3790    fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
3791    fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
3792    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
3793    if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3794        DEBUG_PRINT_ERROR("Failed to set format on capture port");
3795        return false;
3796    }
3797
3798    m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
3799    bufreq.memory = V4L2_MEMORY_USERPTR;
3800    bufreq.count = m_sOutput_buff_property.actualcount;
3801    bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3802    if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3803        DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
3804            return false;
3805    }
3806    if (bufreq.count >= m_sOutput_buff_property.mincount)
3807        m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
3808
3809    return true;
3810}
3811
3812bool venc_dev::venc_set_searchrange()
3813{
3814    DEBUG_PRINT_LOW("venc_set_searchrange");
3815    struct v4l2_control control;
3816    struct v4l2_ext_control ctrl[6];
3817    struct v4l2_ext_controls controls;
3818    int rc;
3819
3820    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3821        ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3822        ctrl[0].value = 16;
3823        ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3824        ctrl[1].value = 4;
3825        ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3826        ctrl[2].value = 16;
3827        ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3828        ctrl[3].value = 4;
3829        ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3830        ctrl[4].value = 12;
3831        ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3832        ctrl[5].value = 4;
3833    } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
3834               (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
3835        ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3836        ctrl[0].value = 16;
3837        ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3838        ctrl[1].value = 4;
3839        ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3840        ctrl[2].value = 16;
3841        ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3842        ctrl[3].value = 4;
3843        ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3844        ctrl[4].value = 12;
3845        ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3846        ctrl[5].value = 4;
3847    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3848        ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3849        ctrl[0].value = 4;
3850        ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3851        ctrl[1].value = 4;
3852        ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3853        ctrl[2].value = 4;
3854        ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3855        ctrl[3].value = 4;
3856        ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3857        ctrl[4].value = 4;
3858        ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3859        ctrl[5].value = 4;
3860    } else {
3861        DEBUG_PRINT_ERROR("Invalid codec type");
3862        return false;
3863    }
3864    controls.count = 6;
3865    controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3866    controls.controls = ctrl;
3867
3868    DEBUG_PRINT_LOW(" Calling IOCTL set control for"
3869        "id=%x, val=%d id=%x, val=%d"
3870        "id=%x, val=%d id=%x, val=%d"
3871        "id=%x, val=%d id=%x, val=%d",
3872        controls.controls[0].id, controls.controls[0].value,
3873        controls.controls[1].id, controls.controls[1].value,
3874        controls.controls[2].id, controls.controls[2].value,
3875        controls.controls[3].id, controls.controls[3].value,
3876        controls.controls[4].id, controls.controls[4].value,
3877        controls.controls[5].id, controls.controls[5].value);
3878
3879    rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3880    if (rc) {
3881        DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
3882        return false;
3883    }
3884    return true;
3885}
3886
3887bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
3888{
3889    bool status = true;
3890    struct v4l2_control control;
3891    int rc = 0;
3892    control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
3893
3894    switch (eControlRate) {
3895        case OMX_Video_ControlRateDisable:
3896            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
3897            break;
3898        case OMX_Video_ControlRateVariableSkipFrames:
3899            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
3900            break;
3901        case OMX_Video_ControlRateVariable:
3902            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
3903            break;
3904        case OMX_Video_ControlRateConstantSkipFrames:
3905            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
3906            break;
3907        case OMX_Video_ControlRateConstant:
3908            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
3909            break;
3910        default:
3911            status = false;
3912            break;
3913    }
3914
3915    if (status) {
3916
3917        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3918        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3919
3920        if (rc) {
3921            DEBUG_PRINT_ERROR("Failed to set control");
3922            return false;
3923        }
3924
3925        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3926
3927        rate_ctrl.rcmode = control.value;
3928    }
3929
3930    return status;
3931}
3932
3933bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
3934{
3935    bool status = true;
3936    struct v4l2_control control;
3937    int rc = 0;
3938    control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
3939
3940    switch (ePerfLevel) {
3941    case OMX_QCOM_PerfLevelNominal:
3942        control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
3943        break;
3944    case OMX_QCOM_PerfLevelTurbo:
3945        control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
3946        break;
3947    default:
3948        status = false;
3949        break;
3950    }
3951
3952    if (status) {
3953        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3954        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3955
3956        if (rc) {
3957            DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
3958            return false;
3959        }
3960
3961        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3962    }
3963    return status;
3964}
3965
3966bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
3967{
3968    struct v4l2_control control;
3969    int rc = 0;
3970    control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
3971
3972    if (enable)
3973        control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
3974    else
3975        control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
3976
3977    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3978    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3979    if (rc) {
3980        DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
3981        return false;
3982    }
3983    DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3984    return true;
3985}
3986
3987bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
3988{
3989    struct v4l2_control control;
3990    int rc = 0;
3991    control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
3992    control.value = nPeakBitrate;
3993
3994    DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
3995
3996    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3997    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3998
3999    if (rc) {
4000        DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
4001        return false;
4002    }
4003
4004    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4005
4006    return true;
4007}
4008
4009bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
4010{
4011    bool status = true;
4012
4013    if (eProfile == NULL || eLevel == NULL) {
4014        return false;
4015    }
4016
4017    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4018        switch (codec_profile.profile) {
4019            case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4020                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4021                break;
4022            case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4023                *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4024                break;
4025            default:
4026                *eProfile = OMX_VIDEO_MPEG4ProfileMax;
4027                status = false;
4028                break;
4029        }
4030
4031        if (!status) {
4032            return status;
4033        }
4034
4035        //profile level
4036        switch (profile_level.level) {
4037            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
4038                *eLevel = OMX_VIDEO_MPEG4Level0;
4039                break;
4040            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
4041                *eLevel = OMX_VIDEO_MPEG4Level0b;
4042                break;
4043            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
4044                *eLevel = OMX_VIDEO_MPEG4Level1;
4045                break;
4046            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
4047                *eLevel = OMX_VIDEO_MPEG4Level2;
4048                break;
4049            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
4050                *eLevel = OMX_VIDEO_MPEG4Level3;
4051                break;
4052            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
4053                *eLevel = OMX_VIDEO_MPEG4Level4;
4054                break;
4055            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
4056                *eLevel = OMX_VIDEO_MPEG4Level5;
4057                break;
4058            default:
4059                *eLevel = OMX_VIDEO_MPEG4LevelMax;
4060                status =  false;
4061                break;
4062        }
4063    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4064        if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
4065            *eProfile = OMX_VIDEO_H263ProfileBaseline;
4066        } else {
4067            *eProfile = OMX_VIDEO_H263ProfileMax;
4068            return false;
4069        }
4070
4071        switch (profile_level.level) {
4072            case VEN_LEVEL_H263_10:
4073                *eLevel = OMX_VIDEO_H263Level10;
4074                break;
4075            case VEN_LEVEL_H263_20:
4076                *eLevel = OMX_VIDEO_H263Level20;
4077                break;
4078            case VEN_LEVEL_H263_30:
4079                *eLevel = OMX_VIDEO_H263Level30;
4080                break;
4081            case VEN_LEVEL_H263_40:
4082                *eLevel = OMX_VIDEO_H263Level40;
4083                break;
4084            case VEN_LEVEL_H263_45:
4085                *eLevel = OMX_VIDEO_H263Level45;
4086                break;
4087            case VEN_LEVEL_H263_50:
4088                *eLevel = OMX_VIDEO_H263Level50;
4089                break;
4090            case VEN_LEVEL_H263_60:
4091                *eLevel = OMX_VIDEO_H263Level60;
4092                break;
4093            case VEN_LEVEL_H263_70:
4094                *eLevel = OMX_VIDEO_H263Level70;
4095                break;
4096            default:
4097                *eLevel = OMX_VIDEO_H263LevelMax;
4098                status = false;
4099                break;
4100        }
4101    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4102        switch (codec_profile.profile) {
4103            case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
4104                *eProfile = OMX_VIDEO_AVCProfileBaseline;
4105                break;
4106            case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
4107                *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
4108                break;
4109            case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4110                *eProfile = OMX_VIDEO_AVCProfileMain;
4111                break;
4112            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4113                *eProfile = OMX_VIDEO_AVCProfileHigh;
4114                break;
4115            case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4116                *eProfile = OMX_VIDEO_AVCProfileExtended;
4117                break;
4118            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4119                *eProfile = OMX_VIDEO_AVCProfileHigh10;
4120                break;
4121            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4122                *eProfile = OMX_VIDEO_AVCProfileHigh422;
4123                break;
4124            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4125                *eProfile = OMX_VIDEO_AVCProfileHigh444;
4126                break;
4127            default:
4128                *eProfile = OMX_VIDEO_AVCProfileMax;
4129                status = false;
4130                break;
4131        }
4132
4133        if (!status) {
4134            return status;
4135        }
4136
4137        switch (profile_level.level) {
4138            case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
4139                *eLevel = OMX_VIDEO_AVCLevel1;
4140                break;
4141            case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
4142                *eLevel = OMX_VIDEO_AVCLevel1b;
4143                break;
4144            case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
4145                *eLevel = OMX_VIDEO_AVCLevel11;
4146                break;
4147            case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
4148                *eLevel = OMX_VIDEO_AVCLevel12;
4149                break;
4150            case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
4151                *eLevel = OMX_VIDEO_AVCLevel13;
4152                break;
4153            case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4154                *eLevel = OMX_VIDEO_AVCLevel2;
4155                break;
4156            case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4157                *eLevel = OMX_VIDEO_AVCLevel21;
4158                break;
4159            case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4160                *eLevel = OMX_VIDEO_AVCLevel22;
4161                break;
4162            case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4163                *eLevel = OMX_VIDEO_AVCLevel3;
4164                break;
4165            case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4166                *eLevel = OMX_VIDEO_AVCLevel31;
4167                break;
4168            case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4169                *eLevel = OMX_VIDEO_AVCLevel32;
4170                break;
4171            case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4172                *eLevel = OMX_VIDEO_AVCLevel4;
4173                break;
4174            case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4175                *eLevel = OMX_VIDEO_AVCLevel41;
4176                break;
4177            case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4178                *eLevel = OMX_VIDEO_AVCLevel42;
4179                break;
4180            case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4181                *eLevel = OMX_VIDEO_AVCLevel5;
4182                break;
4183            case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4184                *eLevel = OMX_VIDEO_AVCLevel51;
4185                break;
4186            case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4187                *eLevel = OMX_VIDEO_AVCLevel52;
4188                break;
4189            default :
4190                *eLevel = OMX_VIDEO_AVCLevelMax;
4191                status = false;
4192                break;
4193        }
4194    }
4195    else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4196        switch (codec_profile.profile) {
4197            case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
4198                *eProfile = OMX_VIDEO_VP8ProfileMain;
4199                break;
4200            default:
4201                *eProfile = OMX_VIDEO_VP8ProfileMax;
4202                status = false;
4203                break;
4204        }
4205        if (!status) {
4206            return status;
4207        }
4208
4209        switch (profile_level.level) {
4210            case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
4211                *eLevel = OMX_VIDEO_VP8Level_Version0;
4212                break;
4213            case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
4214                *eLevel = OMX_VIDEO_VP8Level_Version1;
4215                break;
4216            default:
4217                *eLevel = OMX_VIDEO_VP8LevelMax;
4218                status = false;
4219                break;
4220        }
4221    }
4222
4223    return status;
4224}
4225
4226bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
4227{
4228    OMX_U32 new_profile = 0, new_level = 0;
4229    unsigned const int *profile_tbl = NULL;
4230    OMX_U32 mb_per_frame, mb_per_sec;
4231    bool profile_level_found = false;
4232
4233    DEBUG_PRINT_LOW("Init profile table for respective codec");
4234
4235    //validate the ht,width,fps,bitrate and set the appropriate profile and level
4236    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4237        if (*eProfile == 0) {
4238            if (!m_profile_set) {
4239                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4240            } else {
4241                switch (codec_profile.profile) {
4242                    case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4243                        *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4244                        break;
4245                    case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4246                        *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4247                        break;
4248                    default:
4249                        DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4250                        return false;
4251                }
4252            }
4253        }
4254
4255        if (*eLevel == 0 && !m_level_set) {
4256            *eLevel = OMX_VIDEO_MPEG4LevelMax;
4257        }
4258
4259        if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4260            profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
4261        } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4262            profile_tbl = (unsigned int const *)
4263                (&mpeg4_profile_level_table[MPEG4_ASP_START]);
4264        } else {
4265            DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
4266            return false;
4267        }
4268    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4269        if (*eProfile == 0) {
4270            if (!m_profile_set) {
4271                *eProfile = OMX_VIDEO_AVCProfileBaseline;
4272            } else {
4273                switch (codec_profile.profile) {
4274                    case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
4275                        *eProfile = OMX_VIDEO_AVCProfileBaseline;
4276                        break;
4277                    case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
4278                        *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
4279                        break;
4280                    case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4281                        *eProfile = OMX_VIDEO_AVCProfileMain;
4282                        break;
4283                    case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4284                        *eProfile = OMX_VIDEO_AVCProfileExtended;
4285                        break;
4286                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4287                        *eProfile = OMX_VIDEO_AVCProfileHigh;
4288                        break;
4289                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4290                        *eProfile = OMX_VIDEO_AVCProfileHigh10;
4291                        break;
4292                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4293                        *eProfile = OMX_VIDEO_AVCProfileHigh422;
4294                        break;
4295                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4296                        *eProfile = OMX_VIDEO_AVCProfileHigh444;
4297                        break;
4298                    default:
4299                        DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4300                        return false;
4301                }
4302            }
4303        }
4304
4305        if (*eLevel == 0 && !m_level_set) {
4306            *eLevel = OMX_VIDEO_AVCLevelMax;
4307        }
4308
4309        if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
4310            (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
4311            profile_tbl = (unsigned int const *)h264_profile_level_table;
4312        } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
4313            profile_tbl = (unsigned int const *)
4314                (&h264_profile_level_table[H264_HP_START]);
4315        } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
4316            profile_tbl = (unsigned int const *)
4317                (&h264_profile_level_table[H264_MP_START]);
4318        } else {
4319            DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
4320            return false;
4321        }
4322    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4323        if (*eProfile == 0) {
4324            if (!m_profile_set) {
4325                *eProfile = OMX_VIDEO_H263ProfileBaseline;
4326            } else {
4327                switch (codec_profile.profile) {
4328                    case VEN_PROFILE_H263_BASELINE:
4329                        *eProfile = OMX_VIDEO_H263ProfileBaseline;
4330                        break;
4331                    default:
4332                        DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4333                        return false;
4334                }
4335            }
4336        }
4337
4338        if (*eLevel == 0 && !m_level_set) {
4339            *eLevel = OMX_VIDEO_H263LevelMax;
4340        }
4341
4342        if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
4343            profile_tbl = (unsigned int const *)h263_profile_level_table;
4344        } else {
4345            DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
4346            return false;
4347        }
4348    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4349        if (*eProfile == 0) {
4350            *eProfile = OMX_VIDEO_VP8ProfileMain;
4351        } else {
4352            switch (codec_profile.profile) {
4353                case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
4354                    *eProfile = OMX_VIDEO_VP8ProfileMain;
4355                    break;
4356                default:
4357                    DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
4358                    return false;
4359            }
4360        }
4361        if (*eLevel == 0) {
4362            switch (profile_level.level) {
4363                case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
4364                    *eLevel = OMX_VIDEO_VP8Level_Version0;
4365                    break;
4366                case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
4367                    *eLevel = OMX_VIDEO_VP8Level_Version1;
4368                    break;
4369                default:
4370                    DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
4371                    return false;
4372            }
4373        }
4374        return true;
4375    } else {
4376        DEBUG_PRINT_LOW("Invalid codec type");
4377        return false;
4378    }
4379
4380    mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4381        ((m_sVenc_cfg.dvs_width + 15)>> 4);
4382
4383    if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
4384        if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4385            profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4386
4387        if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4388            profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4389
4390        {
4391            new_level = profile_level.level;
4392            new_profile = codec_profile.profile;
4393            return true;
4394        }
4395    }
4396
4397    mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
4398
4399    do {
4400        if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
4401            if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
4402                if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
4403                    new_level = (int)profile_tbl[3];
4404                    new_profile = (int)profile_tbl[4];
4405                    profile_level_found = true;
4406                    DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (unsigned int)new_profile, (unsigned int)new_level);
4407                    break;
4408                }
4409            }
4410        }
4411
4412        profile_tbl = profile_tbl + 5;
4413    } while (profile_tbl[0] != 0);
4414
4415    if (profile_level_found != true) {
4416        DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
4417        return false;
4418    }
4419
4420    if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
4421            || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) {
4422        *eLevel = new_level;
4423    }
4424
4425    DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
4426            "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
4427
4428    return true;
4429}
4430#ifdef _ANDROID_ICS_
4431bool venc_dev::venc_set_meta_mode(bool mode)
4432{
4433    metadatamode = mode;
4434    return true;
4435}
4436#endif
4437
4438bool venc_dev::venc_is_video_session_supported(unsigned long width,
4439        unsigned long height)
4440{
4441    if ((width * height < capability.min_width *  capability.min_height) ||
4442            (width * height > capability.max_width *  capability.max_height)) {
4443        DEBUG_PRINT_ERROR(
4444                "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
4445                width, height, capability.min_width, capability.min_height,
4446                capability.max_width, capability.max_height);
4447        return false;
4448    }
4449
4450    DEBUG_PRINT_LOW("video session supported");
4451    return true;
4452}
4453