1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2013, 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 <linux/android_pmem.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
43#ifdef _ANDROID_
44#include <media/hardware/HardwareAPI.h>
45#include <gralloc_priv.h>
46#endif
47
48#define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
49
50#define MPEG4_SP_START 0
51#define MPEG4_ASP_START (MPEG4_SP_START + 10)
52#define H263_BP_START 0
53#define H264_BP_START 0
54#define H264_HP_START (H264_BP_START + 17)
55#define H264_MP_START (H264_BP_START + 34)
56#define POLL_TIMEOUT 1000
57#define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
58
59/* MPEG4 profile and level table*/
60static const unsigned int mpeg4_profile_level_table[][5]= {
61    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
62    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
63    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
64    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
65    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
66    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
67    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
68    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
69    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
70    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
71    {0,0,0,0,0},
72
73    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
74    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
75    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
76    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
77    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
78    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
79    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
80    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
81    {0,0,0,0,0},
82};
83
84/* H264 profile and level table*/
85static const unsigned int h264_profile_level_table[][5]= {
86    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
87    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
88    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
89    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
90    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
91    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
92    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
93    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
94    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
95    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
96    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
97    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
98    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
99    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline},
100    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline},
101    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline},
102    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline},
103    {0,0,0,0,0},
104
105    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
106    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
107    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
108    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
109    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
110    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
111    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
112    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
113    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
114    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
115    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
116    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
117    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh},
118    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh},
119    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh},
120    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh},
121    {0,0,0,0,0},
122
123    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
124    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
125    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
126    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
127    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
128    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
129    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
130    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
131    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
132    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
133    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
134    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
135    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain},
136    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain},
137    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain},
138    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain},
139    {0,0,0,0,0}
140
141};
142
143/* H263 profile and level table*/
144static const unsigned int h263_profile_level_table[][5]= {
145    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
146    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
147    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
148    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
149    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
150    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
151    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
152    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
153    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
154    {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
155    {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
156    {0,0,0,0,0}
157};
158
159#define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
160#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
161
162#ifdef INPUT_BUFFER_LOG
163FILE *inputBufferFile1;
164char inputfilename [] = "/data/input.yuv";
165#endif
166#ifdef OUTPUT_BUFFER_LOG
167FILE *outputBufferFile1;
168char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
169#endif
170
171//constructor
172venc_dev::venc_dev(class omx_venc *venc_class)
173{
174    //nothing to do
175    int i = 0;
176    venc_handle = venc_class;
177    etb = ebd = ftb = fbd = 0;
178
179    for (i = 0; i < MAX_PORT; i++)
180        streaming[i] = false;
181
182    stopped = 1;
183    paused = false;
184    async_thread_created = false;
185    color_format = 0;
186    pthread_mutex_init(&pause_resume_mlock, NULL);
187    pthread_cond_init(&pause_resume_cond, NULL);
188    memset(&extradata_info, 0, sizeof(extradata_info));
189    memset(&idrperiod, 0, sizeof(idrperiod));
190    memset(&multislice, 0, sizeof(multislice));
191    memset (&slice_mode, 0 , sizeof(slice_mode));
192    memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
193    memset(&rate_ctrl, 0, sizeof(rate_ctrl));
194    memset(&bitrate, 0, sizeof(bitrate));
195    memset(&intra_period, 0, sizeof(intra_period));
196    memset(&codec_profile, 0, sizeof(codec_profile));
197    memset(&set_param, 0, sizeof(set_param));
198    memset(&time_inc, 0, sizeof(time_inc));
199    memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
200    memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
201    memset(&session_qp, 0, sizeof(session_qp));
202    memset(&entropy, 0, sizeof(entropy));
203    memset(&dbkfilter, 0, sizeof(dbkfilter));
204    memset(&intra_refresh, 0, sizeof(intra_refresh));
205    memset(&hec, 0, sizeof(hec));
206    memset(&voptimecfg, 0, sizeof(voptimecfg));
207    memset(&capability, 0, sizeof(capability));
208}
209
210venc_dev::~venc_dev()
211{
212    //nothing to do
213}
214
215void* venc_dev::async_venc_message_thread (void *input)
216{
217    struct venc_msg venc_msg;
218    omx_video* omx_venc_base = NULL;
219    omx_venc *omx = reinterpret_cast<omx_venc*>(input);
220    omx_venc_base = reinterpret_cast<omx_video*>(input);
221    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
222
223    prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
224    struct v4l2_plane plane[VIDEO_MAX_PLANES];
225    struct pollfd pfd;
226    struct v4l2_buffer v4l2_buf;
227    struct v4l2_event dqevent;
228    pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
229    pfd.fd = omx->handle->m_nDriver_fd;
230    int error_code = 0,rc=0;
231
232    memset(&v4l2_buf, 0, sizeof(v4l2_buf));
233
234    while (1) {
235        pthread_mutex_lock(&omx->handle->pause_resume_mlock);
236
237        if (omx->handle->paused) {
238            venc_msg.msgcode = VEN_MSG_PAUSE;
239            venc_msg.statuscode = VEN_S_SUCCESS;
240
241            if (omx->async_message_process(input, &venc_msg) < 0) {
242                DEBUG_PRINT_ERROR("\nERROR: Failed to process pause msg");
243                pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
244                break;
245            }
246
247            /* Block here until the IL client resumes us again */
248            pthread_cond_wait(&omx->handle->pause_resume_cond,
249                    &omx->handle->pause_resume_mlock);
250
251            venc_msg.msgcode = VEN_MSG_RESUME;
252            venc_msg.statuscode = VEN_S_SUCCESS;
253
254            if (omx->async_message_process(input, &venc_msg) < 0) {
255                DEBUG_PRINT_ERROR("\nERROR: Failed to process resume msg");
256                pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
257                break;
258            }
259        }
260
261        pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
262
263        rc = poll(&pfd, 1, POLL_TIMEOUT);
264
265        if (!rc) {
266            DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d\n",
267                    omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
268            continue;
269        } else if (rc < 0) {
270            DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
271            break;
272        }
273
274        if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
275            v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
276            v4l2_buf.memory = V4L2_MEMORY_USERPTR;
277            v4l2_buf.length = omx->handle->num_planes;
278            v4l2_buf.m.planes = plane;
279
280            while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
281                venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
282                venc_msg.statuscode=VEN_S_SUCCESS;
283                omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
284                venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
285                venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
286                venc_msg.buf.flags = 0;
287                venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
288                venc_msg.buf.clientdata=(void*)omxhdr;
289                venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
290
291                /* TODO: ideally report other types of frames as well
292                 * for now it doesn't look like IL client cares about
293                 * other types
294                 */
295                if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
296                    venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
297
298                if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
299                    venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
300
301                if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
302                    venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
303
304                if (v4l2_buf.flags & V4L2_BUF_FLAG_EOS)
305                    venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
306
307                if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
308                    venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
309
310                omx->handle->fbd++;
311
312                if (omx->async_message_process(input,&venc_msg) < 0) {
313                    DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
314                    break;
315                }
316            }
317        }
318
319        if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
320            v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
321            v4l2_buf.memory = V4L2_MEMORY_USERPTR;
322            v4l2_buf.m.planes = plane;
323            v4l2_buf.length = 1;
324
325            while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
326                venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
327                venc_msg.statuscode=VEN_S_SUCCESS;
328                omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
329                venc_msg.buf.clientdata=(void*)omxhdr;
330                omx->handle->ebd++;
331
332                if (omx->async_message_process(input,&venc_msg) < 0) {
333                    DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
334                    break;
335                }
336            }
337        }
338
339        if (pfd.revents & POLLPRI) {
340            rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
341
342            if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
343                DEBUG_PRINT_HIGH("CLOSE DONE\n");
344                break;
345            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
346                venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
347                venc_msg.statuscode = VEN_S_SUCCESS;
348
349                if (omx->async_message_process(input,&venc_msg) < 0) {
350                    DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
351                    break;
352                }
353
354                venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
355                venc_msg.statuscode = VEN_S_SUCCESS;
356
357                if (omx->async_message_process(input,&venc_msg) < 0) {
358                    DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
359                    break;
360                }
361            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
362                DEBUG_PRINT_ERROR("\n HW Error recieved \n");
363                venc_msg.statuscode=VEN_S_EFAIL;
364
365                if (omx->async_message_process(input,&venc_msg) < 0) {
366                    DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
367                    break;
368                }
369            }
370        }
371    }
372
373    DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
374    return NULL;
375}
376
377static const int event_type[] = {
378    V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
379    V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
380    V4L2_EVENT_MSM_VIDC_SYS_ERROR
381};
382
383static OMX_ERRORTYPE subscribe_to_events(int fd)
384{
385    OMX_ERRORTYPE eRet = OMX_ErrorNone;
386    struct v4l2_event_subscription sub;
387    int array_sz = sizeof(event_type)/sizeof(int);
388    int i,rc;
389    memset(&sub, 0, sizeof(sub));
390
391    if (fd < 0) {
392        printf("Invalid input: %d\n", fd);
393        return OMX_ErrorBadParameter;
394    }
395
396    for (i = 0; i < array_sz; ++i) {
397        memset(&sub, 0, sizeof(sub));
398        sub.type = event_type[i];
399        rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
400
401        if (rc) {
402            printf("Failed to subscribe event: 0x%x\n", sub.type);
403            break;
404        }
405    }
406
407    if (i < array_sz) {
408        for (--i; i >=0 ; i--) {
409            memset(&sub, 0, sizeof(sub));
410            sub.type = event_type[i];
411            rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
412
413            if (rc)
414                printf("Failed to unsubscribe event: 0x%x\n", sub.type);
415        }
416
417        eRet = OMX_ErrorNotImplemented;
418    }
419
420    return eRet;
421}
422
423bool venc_dev::handle_extradata(void *buffer, int index)
424{
425    OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
426    OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
427
428    if (!extradata_info.uaddr) {
429        DEBUG_PRINT_ERROR("Extradata buffers not allocated\n");
430        return false;
431    }
432
433    p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(p_bufhdr->pBuffer + p_bufhdr->nOffset + p_bufhdr->nFilledLen + 3)&(~3));
434    char *p_extradata = extradata_info.uaddr + index * extradata_info.buffer_size;
435
436    if ((OMX_U8*)p_extra > (p_bufhdr->pBuffer + p_bufhdr->nAllocLen)) {
437        DEBUG_PRINT_ERROR("Insufficient buffer size\n");
438        p_extra = NULL;
439        return false;
440    }
441
442    memcpy(p_extra, p_extradata, extradata_info.buffer_size);
443    return true;
444}
445
446int venc_dev::venc_set_format(int format)
447{
448    int rc = true;
449
450    if (format)
451        color_format = format;
452    else {
453        color_format = 0;
454        rc = false;
455    }
456
457    return rc;
458}
459
460OMX_ERRORTYPE venc_dev::allocate_extradata()
461{
462    if (extradata_info.allocated) {
463        DEBUG_PRINT_ERROR("2nd allocation return");
464        return OMX_ErrorNone;
465    }
466
467#ifdef USE_ION
468
469    if (extradata_info.buffer_size) {
470        if (extradata_info.ion.ion_alloc_data.handle) {
471            munmap((void *)extradata_info.uaddr, extradata_info.size);
472            close(extradata_info.ion.fd_ion_data.fd);
473            free_ion_memory(&extradata_info.ion);
474        }
475
476        extradata_info.size = (extradata_info.size + 4095) & (~4095);
477
478        extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
479                extradata_info.size,
480                &extradata_info.ion.ion_alloc_data,
481                &extradata_info.ion.fd_ion_data, 0);
482
483        if (extradata_info.ion.ion_device_fd < 0) {
484            DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
485            return OMX_ErrorInsufficientResources;
486        }
487
488        extradata_info.uaddr = (char *)mmap(NULL,
489                extradata_info.size,
490                PROT_READ|PROT_WRITE, MAP_SHARED,
491                extradata_info.ion.fd_ion_data.fd , 0);
492
493        if (extradata_info.uaddr == MAP_FAILED) {
494            DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
495            close(extradata_info.ion.fd_ion_data.fd);
496            free_ion_memory(&extradata_info.ion);
497            return OMX_ErrorInsufficientResources;
498        }
499    }
500
501#endif
502    extradata_info.allocated = 1;
503    return OMX_ErrorNone;
504}
505
506void venc_dev::free_extradata()
507{
508#ifdef USE_ION
509
510    if (extradata_info.uaddr) {
511        munmap((void *)extradata_info.uaddr, extradata_info.size);
512        close(extradata_info.ion.fd_ion_data.fd);
513        free_ion_memory(&extradata_info.ion);
514    }
515
516    memset(&extradata_info, 0, sizeof(extradata_info));
517#endif
518}
519
520bool venc_dev::venc_open(OMX_U32 codec)
521{
522    int r;
523    unsigned int alignment = 0,buffer_size = 0, temp =0;
524    struct v4l2_control control;
525    OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc";
526
527    char platform_name[PROPERTY_VALUE_MAX];
528    property_get("ro.board.platform", platform_name, "0");
529
530    if (!strncmp(platform_name, "msm8610", 7)) {
531        device_name = (OMX_STRING)"/dev/video/q6_enc";
532    }
533
534    m_nDriver_fd = open (device_name, O_RDWR);
535
536    if (m_nDriver_fd == 0) {
537        DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
538        m_nDriver_fd = open (device_name, O_RDWR);
539    }
540
541    if ((int)m_nDriver_fd < 0) {
542        DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
543        return false;
544    }
545
546    DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
547    // set the basic configuration of the video encoder driver
548    m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
549    m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
550    m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
551    m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
552    m_sVenc_cfg.fps_num = 30;
553    m_sVenc_cfg.fps_den = 1;
554    m_sVenc_cfg.targetbitrate = 64000;
555    m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
556
557    if (codec == OMX_VIDEO_CodingMPEG4) {
558        m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
559        codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
560        profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
561#ifdef OUTPUT_BUFFER_LOG
562        strcat(outputfilename, "m4v");
563#endif
564    } else if (codec == OMX_VIDEO_CodingH263) {
565        m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
566        codec_profile.profile = VEN_PROFILE_H263_BASELINE;
567        profile_level.level = VEN_LEVEL_H263_20;
568#ifdef OUTPUT_BUFFER_LOG
569        strcat(outputfilename, "263");
570#endif
571    } else if (codec == OMX_VIDEO_CodingAVC) {
572        m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
573        codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
574        profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
575#ifdef OUTPUT_BUFFER_LOG
576        strcat(outputfilename, "264");
577#endif
578    } else if (codec == OMX_VIDEO_CodingVPX) {
579        m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
580        codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
581        profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
582#ifdef OUTPUT_BUFFER_LOG
583        strcat(outputfilename, "ivf");
584#endif
585    }
586
587#ifdef INPUT_BUFFER_LOG
588    inputBufferFile1 = fopen (inputfilename, "ab");
589
590    if (!inputBufferFile1)
591        DEBUG_PRINT_ERROR("Input File open failed");
592
593#endif
594#ifdef OUTPUT_BUFFER_LOG
595    outputBufferFile1 = fopen (outputfilename, "ab");
596#endif
597    int ret;
598    ret = subscribe_to_events(m_nDriver_fd);
599
600    if (ret) {
601        DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
602        return false;
603    }
604
605    struct v4l2_capability cap;
606
607    struct v4l2_fmtdesc fdesc;
608
609    struct v4l2_format fmt;
610
611    struct v4l2_requestbuffers bufreq;
612
613    ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
614
615    if (ret) {
616        DEBUG_PRINT_ERROR("Failed to query capabilities\n");
617    } else {
618        DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
619                " version = %d, capabilities = %x\n", cap.driver, cap.card,
620                cap.bus_info, cap.version, cap.capabilities);
621    }
622
623    ret=0;
624    fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
625    fdesc.index=0;
626
627    while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
628        DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
629                fdesc.pixelformat, fdesc.flags);
630        fdesc.index++;
631    }
632
633    fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
634    fdesc.index=0;
635
636    while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
637        DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
638                fdesc.pixelformat, fdesc.flags);
639        fdesc.index++;
640    }
641
642    m_sOutput_buff_property.alignment=m_sInput_buff_property.alignment=4096;
643    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
644    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
645    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
646    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
647
648    /*TODO: Return values not handled properly in this function anywhere.
649     * Need to handle those.*/
650    ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
651
652    if (ret) {
653        DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
654        return false;
655    }
656
657    m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
658
659    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
660    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
661    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
662    fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
663
664    ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
665    m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
666
667    bufreq.memory = V4L2_MEMORY_USERPTR;
668    bufreq.count = 2;
669
670    bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
671    ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
672    m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
673
674    bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
675    bufreq.count = 2;
676    ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
677    m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
678
679
680    resume_in_stopped = 0;
681    metadatamode = 0;
682
683    control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
684    control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
685
686    DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d\n", control.id, control.value);
687
688    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
689        DEBUG_PRINT_ERROR("Failed to set control\n");
690
691    struct v4l2_frmsizeenum frmsize;
692
693    //Get the hardware capabilities
694    memset((void *)&frmsize,0,sizeof(frmsize));
695    frmsize.index = 0;
696    frmsize.pixel_format = m_sVenc_cfg.codectype;
697    ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
698
699    if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
700        DEBUG_PRINT_ERROR("Failed to get framesizes\n");
701        return false;
702    }
703
704    if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
705        capability.min_width = frmsize.stepwise.min_width;
706        capability.max_width = frmsize.stepwise.max_width;
707        capability.min_height = frmsize.stepwise.min_height;
708        capability.max_height = frmsize.stepwise.max_height;
709    }
710
711    return true;
712}
713
714
715static OMX_ERRORTYPE unsubscribe_to_events(int fd)
716{
717    OMX_ERRORTYPE eRet = OMX_ErrorNone;
718    struct v4l2_event_subscription sub;
719    int array_sz = sizeof(event_type)/sizeof(int);
720    int i,rc;
721
722    if (fd < 0) {
723        printf("Invalid input: %d\n", fd);
724        return OMX_ErrorBadParameter;
725    }
726
727    for (i = 0; i < array_sz; ++i) {
728        memset(&sub, 0, sizeof(sub));
729        sub.type = event_type[i];
730        rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
731
732        if (rc) {
733            printf("Failed to unsubscribe event: 0x%x\n", sub.type);
734            break;
735        }
736    }
737
738    return eRet;
739}
740
741void venc_dev::venc_close()
742{
743    struct v4l2_encoder_cmd enc;
744    DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
745
746    if ((int)m_nDriver_fd >= 0) {
747        enc.cmd = V4L2_ENC_CMD_STOP;
748        ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
749        DEBUG_PRINT_HIGH("venc_close E\n");
750
751        if (async_thread_created)
752            pthread_join(m_tid,NULL);
753
754        DEBUG_PRINT_HIGH("venc_close X\n");
755        unsubscribe_to_events(m_nDriver_fd);
756        close(m_nDriver_fd);
757        m_nDriver_fd = -1;
758    }
759
760#ifdef INPUT_BUFFER_LOG
761    fclose (inputBufferFile1);
762#endif
763#ifdef OUTPUT_BUFFER_LOG
764    fclose (outputBufferFile1);
765#endif
766}
767
768bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
769        unsigned long *actual_buff_count,
770        unsigned long *buff_size,
771        unsigned long port)
772{
773
774    unsigned long temp_count = 0;
775
776    if (port == 0) {
777        if (*actual_buff_count > m_sInput_buff_property.mincount) {
778            temp_count = m_sInput_buff_property.actualcount;
779            m_sInput_buff_property.actualcount = *actual_buff_count;
780            DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
781        }
782    } else {
783        if (*actual_buff_count > m_sOutput_buff_property.mincount) {
784            temp_count = m_sOutput_buff_property.actualcount;
785            m_sOutput_buff_property.actualcount = *actual_buff_count;
786            DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
787        }
788    }
789
790    return true;
791
792}
793
794bool venc_dev::venc_loaded_start()
795{
796    return true;
797}
798
799bool venc_dev::venc_loaded_stop()
800{
801    return true;
802}
803
804bool venc_dev::venc_loaded_start_done()
805{
806    return true;
807}
808
809bool venc_dev::venc_loaded_stop_done()
810{
811    return true;
812}
813
814bool venc_dev::venc_get_seq_hdr(void *buffer,
815        unsigned buffer_size, unsigned *header_len)
816{
817    return true;
818}
819
820bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
821        unsigned long *actual_buff_count,
822        unsigned long *buff_size,
823        unsigned long port)
824{
825    struct v4l2_format fmt;
826    struct v4l2_requestbuffers bufreq;
827    unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
828    int ret;
829
830    if (port == 0) {
831        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
832        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
833        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
834        fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
835        ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
836        m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
837        bufreq.memory = V4L2_MEMORY_USERPTR;
838
839        if (*actual_buff_count)
840            bufreq.count = *actual_buff_count;
841        else
842            bufreq.count = 2;
843
844        bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
845        ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
846
847        if (ret) {
848            DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n ");
849            return false;
850        }
851
852        m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
853        *min_buff_count = m_sInput_buff_property.mincount;
854        *actual_buff_count = m_sInput_buff_property.actualcount;
855#ifdef USE_ION
856        // For ION memory allocations of the allocated buffer size
857        // must be 4k aligned, hence aligning the input buffer
858        // size to 4k.
859        m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) & (~4095);
860#endif
861        *buff_size = m_sInput_buff_property.datasize;
862    } else {
863        int extra_idx = 0;
864        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
865        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
866        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
867        fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
868
869        ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
870        m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
871        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
872        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
873        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
874        fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
875
876        ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
877        m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
878        bufreq.memory = V4L2_MEMORY_USERPTR;
879
880        if (*actual_buff_count)
881            bufreq.count = *actual_buff_count;
882        else
883            bufreq.count = 2;
884
885        bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
886        ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
887
888        if (ret) {
889            DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS CAPTURE_MPLANE Failed \n ");
890            return false;
891        }
892
893        m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
894        *min_buff_count = m_sOutput_buff_property.mincount;
895        *actual_buff_count = m_sOutput_buff_property.actualcount;
896        *buff_size = m_sOutput_buff_property.datasize;
897        num_planes = fmt.fmt.pix_mp.num_planes;
898        extra_idx = EXTRADATA_IDX(num_planes);
899
900        if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
901            extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
902        } else if (extra_idx >= VIDEO_MAX_PLANES) {
903            DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
904            return OMX_ErrorBadParameter;
905        }
906
907        extradata_info.buffer_size = extra_data_size;
908        extradata_info.count = m_sOutput_buff_property.actualcount;
909        extradata_info.size = extradata_info.buffer_size * extradata_info.count;
910    }
911
912    return true;
913}
914
915bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
916{
917    DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
918    struct v4l2_format fmt;
919    struct v4l2_requestbuffers bufreq;
920    int ret;
921
922    switch (index) {
923        case OMX_IndexParamPortDefinition:
924            {
925                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
926                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
927                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n");
928
929                if (portDefn->nPortIndex == PORT_INDEX_IN) {
930                    if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
931                        return false;
932                    }
933
934                    if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
935                        return false;
936                    }
937
938                    if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
939                            m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
940                        DEBUG_PRINT_LOW("\n Basic parameter has changed");
941                        m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
942                        m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
943                        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
944                        fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
945                        fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
946                        fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
947
948                        if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
949                            DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT OUTPUT_MPLANE Failed \n ");
950                            return false;
951                        }
952
953                        m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
954                        bufreq.memory = V4L2_MEMORY_USERPTR;
955                        bufreq.count = portDefn->nBufferCountActual;
956                        bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
957
958                        if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
959                            DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n ");
960                            return false;
961                        }
962
963                        if (bufreq.count == portDefn->nBufferCountActual)
964                            m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
965
966                        if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
967                            m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
968                    }
969
970                    DEBUG_PRINT_LOW("input: actual: %d, min: %d, count_req: %d\n",
971                            portDefn->nBufferCountActual, m_sInput_buff_property.mincount, bufreq.count);
972                } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
973                    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
974                    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
975                    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
976                    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
977
978                    if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
979                        DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT CAPTURE_MPLANE Failed \n ");
980                        return false;
981                    }
982
983                    m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
984
985                    if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
986                        return false;
987                    }
988
989                    if ((portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
990                            && (m_sOutput_buff_property.datasize == portDefn->nBufferSize)) {
991                        m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
992                        bufreq.memory = V4L2_MEMORY_USERPTR;
993                        bufreq.count = portDefn->nBufferCountActual;
994                        bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
995
996                        if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
997                            DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed: requested: %lu, current: %lu",
998                                    portDefn->nBufferCountActual, m_sOutput_buff_property.actualcount);
999                            return false;
1000                        }
1001
1002                        if (bufreq.count == portDefn->nBufferCountActual)
1003                            m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1004
1005                        if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1006                            m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1007
1008                        if (num_planes > 1)
1009                            extradata_info.count = m_sOutput_buff_property.actualcount;
1010                    } else {
1011                        DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
1012                        return false;
1013                    }
1014
1015                    DEBUG_PRINT_LOW("Output: actual: %d, min: %d, count_req: %d\n",
1016                            portDefn->nBufferCountActual, m_sOutput_buff_property.mincount, bufreq.count);
1017                } else {
1018                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1019                }
1020
1021                break;
1022            }
1023        case OMX_IndexParamVideoPortFormat:
1024            {
1025                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1026                portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1027                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
1028
1029                if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1030                    if (!venc_set_color_format(portFmt->eColorFormat)) {
1031                        return false;
1032                    }
1033                } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1034                    if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1035                        return false;
1036                    }
1037                } else {
1038                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1039                }
1040
1041                break;
1042            }
1043        case OMX_IndexParamVideoBitrate:
1044            {
1045                OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1046                pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1047                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
1048
1049                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1050                    if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1051                        DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
1052                        return false;
1053                    }
1054
1055                    if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1056                        DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
1057                        return false;
1058                    }
1059                } else {
1060                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1061                }
1062
1063                break;
1064            }
1065        case OMX_IndexParamVideoMpeg4:
1066            {
1067                OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1068                OMX_U32 bFrames = 0;
1069
1070                pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1071                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
1072
1073                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1074                    if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1075                        DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
1076                        return false;
1077                    }
1078
1079                    m_profile_set = false;
1080                    m_level_set = false;
1081
1082                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1083                        DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
1084                        return false;
1085                    } else {
1086                        if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1087                            if (pParam->nBFrames) {
1088                                DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
1089                                bFrames = 1;
1090                            }
1091                        } else {
1092                            if (pParam->nBFrames) {
1093                                DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
1094                                bFrames = 0;
1095                            }
1096                        }
1097                    }
1098
1099                    if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
1100                        DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
1101                        return false;
1102                    }
1103
1104                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1105                        DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
1106                        return false;
1107                    }
1108                } else {
1109                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1110                }
1111
1112                break;
1113            }
1114        case OMX_IndexParamVideoH263:
1115            {
1116                OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1117                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
1118                OMX_U32 bFrames = 0;
1119
1120                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1121                    m_profile_set = false;
1122                    m_level_set = false;
1123
1124                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1125                        DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
1126                        return false;
1127                    }
1128
1129                    if (pParam->nBFrames)
1130                        DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");
1131
1132                    if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
1133                        DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
1134                        return false;
1135                    }
1136                } else {
1137                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1138                }
1139
1140                break;
1141            }
1142        case OMX_IndexParamVideoAvc:
1143            {
1144                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
1145                OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1146                OMX_U32 bFrames = 0;
1147
1148                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1149                    DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
1150                            pParam->eProfile,pParam->eLevel);
1151
1152                    m_profile_set = false;
1153                    m_level_set = false;
1154
1155                    if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1156                        DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
1157                                pParam->eProfile, pParam->eLevel);
1158                        return false;
1159                    } else {
1160                        if (pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) {
1161                            if (pParam->nBFrames) {
1162                                DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
1163                                bFrames = 1;
1164                            }
1165                        } else {
1166                            if (pParam->nBFrames) {
1167                                DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
1168                                bFrames = 0;
1169                            }
1170                        }
1171                    }
1172
1173                    if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
1174                        DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
1175                        return false;
1176                    }
1177
1178                    if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1179                        DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
1180                        return false;
1181                    }
1182
1183                    if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1184                        DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
1185                        return false;
1186                    }
1187
1188                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1189                        DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
1190                        return false;
1191                    }
1192                } else {
1193                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1194                }
1195
1196                //TBD, lot of other variables to be updated, yet to decide
1197                break;
1198            }
1199        case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1200            {
1201                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8\n");
1202                OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1203                if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1204                    DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
1205                                        pParam->eProfile, pParam->eLevel);
1206                    return false;
1207                }
1208                break;
1209            }
1210        case OMX_IndexParamVideoIntraRefresh:
1211            {
1212                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
1213                OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1214                    (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1215
1216                if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1217                    if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1218                        DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
1219                        return false;
1220                    }
1221                } else {
1222                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1223                }
1224
1225                break;
1226            }
1227        case OMX_IndexParamVideoErrorCorrection:
1228            {
1229                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
1230                OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1231                    (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1232
1233                if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1234                    if (venc_set_error_resilience(error_resilience) == false) {
1235                        DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
1236                        return false;
1237                    }
1238                } else {
1239                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1240                }
1241
1242                break;
1243            }
1244        case OMX_IndexParamVideoProfileLevelCurrent:
1245            {
1246                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
1247                OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1248                    (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1249
1250                if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1251                    m_profile_set = false;
1252                    m_level_set = false;
1253
1254                    if (!venc_set_profile_level (profile_level->eProfile,
1255                                profile_level->eLevel)) {
1256                        DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
1257                        return false;
1258                    }
1259                } else {
1260                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1261                }
1262
1263                break;
1264            }
1265        case OMX_IndexParamVideoQuantization:
1266            {
1267                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
1268                OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1269                    (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1270
1271                if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1272                    if (venc_set_session_qp (session_qp->nQpI,
1273                                session_qp->nQpP,
1274                                session_qp->nQpB) == false) {
1275                        DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
1276                        return false;
1277                    }
1278                } else {
1279                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1280                }
1281
1282                break;
1283            }
1284        case OMX_QcomIndexEnableSliceDeliveryMode:
1285            {
1286                QOMX_EXTNINDEX_PARAMTYPE* pParam =
1287                    (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1288
1289                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1290                    if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1291                        DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1292                        return OMX_ErrorUnsupportedSetting;
1293                    }
1294                } else {
1295                    DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1296                            "called on wrong port(%d)", pParam->nPortIndex);
1297                    return OMX_ErrorBadPortIndex;
1298                }
1299
1300                break;
1301            }
1302        case OMX_ExtraDataVideoEncoderSliceInfo:
1303            {
1304                DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1305                OMX_U32 extra_data = *(OMX_U32 *)paramData;
1306
1307                if (venc_set_extradata(extra_data) == false) {
1308                    DEBUG_PRINT_ERROR("ERROR: Setting "
1309                            "OMX_ExtraDataVideoEncoderSliceInfo failed");
1310                    return false;
1311                }
1312
1313                extradata = true;
1314                break;
1315            }
1316        case OMX_IndexParamVideoSliceFMO:
1317        default:
1318            DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u",
1319                    index);
1320            break;
1321            //case
1322    }
1323
1324    return true;
1325}
1326
1327bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1328{
1329
1330    DEBUG_PRINT_LOW("\n Inside venc_set_config");
1331
1332    switch (index) {
1333        case OMX_IndexConfigVideoBitrate:
1334            {
1335                OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1336                    configData;
1337                DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
1338
1339                if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1340                    if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1341                        DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
1342                        return false;
1343                    }
1344                } else {
1345                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1346                }
1347
1348                break;
1349            }
1350        case OMX_IndexConfigVideoFramerate:
1351            {
1352                OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1353                    configData;
1354                DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
1355
1356                if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1357                    if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1358                        DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
1359                        return false;
1360                    }
1361                } else {
1362                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1363                }
1364
1365                break;
1366            }
1367        case QOMX_IndexConfigVideoIntraperiod:
1368            {
1369                DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
1370                QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1371                    (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1372
1373                if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1374                    if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1375                        DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
1376                        return false;
1377                    }
1378                }
1379
1380                break;
1381            }
1382        case OMX_IndexConfigVideoIntraVOPRefresh:
1383            {
1384                OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1385                    configData;
1386                DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1387
1388                if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1389                    if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
1390                        DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
1391                        return false;
1392                    }
1393                } else {
1394                    DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1395                }
1396
1397                break;
1398            }
1399        case OMX_IndexConfigCommonRotate:
1400            {
1401                OMX_CONFIG_ROTATIONTYPE *config_rotation =
1402                    reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1403                OMX_U32 nFrameWidth;
1404
1405                DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
1406                nFrameWidth = m_sVenc_cfg.input_width;
1407                m_sVenc_cfg.input_width  = m_sVenc_cfg.input_height;
1408                m_sVenc_cfg.input_height = nFrameWidth;
1409
1410                if (/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0) {
1411                    DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
1412                    return false;
1413                }
1414
1415                break;
1416            }
1417        case OMX_IndexConfigVideoAVCIntraPeriod:
1418            {
1419                OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
1420                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
1421
1422                if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
1423                        == false) {
1424                    DEBUG_PRINT_ERROR("ERROR: Setting "
1425                            "OMX_IndexConfigVideoAVCIntraPeriod failed");
1426                    return false;
1427                }
1428
1429                break;
1430            }
1431        default:
1432            DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index);
1433            break;
1434    }
1435
1436    return true;
1437}
1438
1439unsigned venc_dev::venc_stop( void)
1440{
1441    struct venc_msg venc_msg;
1442    struct v4l2_requestbuffers bufreq;
1443    int rc = 0, ret = 0;
1444
1445    if (!stopped) {
1446        enum v4l2_buf_type cap_type;
1447
1448        if (streaming[OUTPUT_PORT]) {
1449            cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1450            rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1451
1452            if (rc) {
1453                DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n",
1454                        cap_type, rc);
1455            } else
1456                streaming[OUTPUT_PORT] = false;
1457
1458            DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
1459            bufreq.memory = V4L2_MEMORY_USERPTR;
1460            bufreq.count = 0;
1461            bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1462            ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1463
1464            if (ret) {
1465                DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed \n ");
1466                return false;
1467            }
1468        }
1469
1470        if (!rc && streaming[CAPTURE_PORT]) {
1471            cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1472            rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1473
1474            if (rc) {
1475                DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n",
1476                        cap_type, rc);
1477            } else
1478                streaming[CAPTURE_PORT] = false;
1479
1480            DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
1481            bufreq.memory = V4L2_MEMORY_USERPTR;
1482            bufreq.count = 0;
1483            bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1484            ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1485
1486            if (ret) {
1487                DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed \n ");
1488                return false;
1489            }
1490        }
1491
1492        if (!rc && !ret) {
1493            venc_stop_done();
1494            stopped = 1;
1495            /*set flag to re-configure when started again*/
1496            resume_in_stopped = 1;
1497
1498        }
1499    }
1500
1501    return rc;
1502}
1503
1504unsigned venc_dev::venc_pause(void)
1505{
1506    pthread_mutex_lock(&pause_resume_mlock);
1507    paused = true;
1508    pthread_mutex_unlock(&pause_resume_mlock);
1509    return 0;
1510}
1511
1512unsigned venc_dev::venc_resume(void)
1513{
1514    pthread_mutex_lock(&pause_resume_mlock);
1515    paused = false;
1516    pthread_mutex_unlock(&pause_resume_mlock);
1517
1518    return pthread_cond_signal(&pause_resume_cond);
1519}
1520
1521unsigned venc_dev::venc_start_done(void)
1522{
1523    struct venc_msg venc_msg;
1524    venc_msg.msgcode = VEN_MSG_START;
1525    venc_msg.statuscode = VEN_S_SUCCESS;
1526    venc_handle->async_message_process(venc_handle,&venc_msg);
1527    return 0;
1528}
1529
1530unsigned venc_dev::venc_stop_done(void)
1531{
1532    struct venc_msg venc_msg;
1533    free_extradata();
1534    venc_msg.msgcode=VEN_MSG_STOP;
1535    venc_msg.statuscode=VEN_S_SUCCESS;
1536    venc_handle->async_message_process(venc_handle,&venc_msg);
1537    return 0;
1538}
1539
1540unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
1541{
1542    async_thread_created = true;
1543    m_tid=tid;
1544    return 0;
1545}
1546
1547
1548unsigned venc_dev::venc_start(void)
1549{
1550    enum v4l2_buf_type buf_type;
1551    int ret,r;
1552    struct v4l2_control control = {0};
1553
1554    DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
1555            __func__);
1556
1557    if (!venc_set_profile_level(0, 0)) {
1558        DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
1559                __func__);
1560    } else {
1561        DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
1562                __func__, codec_profile.profile, profile_level.level);
1563    }
1564
1565    venc_config_print();
1566
1567    if(resume_in_stopped){
1568        /*set buffercount when restarted*/
1569        venc_reconfig_reqbufs();
1570        resume_in_stopped = 0;
1571    }
1572
1573    /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
1574    if (slice_mode.enable && multislice.mslice_size &&
1575            (m_sVenc_cfg.input_width *  m_sVenc_cfg.input_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
1576        DEBUG_PRINT_ERROR("slice_mode: %d, max slices (%d) should be less than (%d)\n", slice_mode.enable,
1577                (m_sVenc_cfg.input_width *  m_sVenc_cfg.input_height)/(256 * multislice.mslice_size),
1578                MAX_SUPPORTED_SLICES_PER_FRAME);
1579        return 1;
1580    }
1581
1582    buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1583    DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1584    ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
1585
1586    if (ret)
1587        return 1;
1588
1589    streaming[CAPTURE_PORT] = true;
1590
1591    control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
1592    control.value = 1;
1593    ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
1594    if (ret) {
1595        DEBUG_PRINT_ERROR("failed to request seq header");
1596        return 1;
1597    }
1598
1599    stopped = 0;
1600    return 0;
1601}
1602
1603void venc_dev::venc_config_print()
1604{
1605
1606    DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
1607            m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
1608
1609    DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %ld, Height:%ld, Fps: %ld",
1610            m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
1611            m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
1612
1613    DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld",
1614            bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
1615
1616    DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
1617            session_qp.iframeqp, session_qp.pframqp,session_qp.bframqp);
1618
1619    DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
1620            voptimecfg.voptime_resolution, multislice.mslice_mode,
1621            multislice.mslice_size);
1622
1623    DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
1624            entropy.longentropysel, entropy.cabacmodel);
1625
1626    DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld\n",
1627            dbkfilter.db_mode, dbkfilter.slicealpha_offset,
1628            dbkfilter.slicebeta_offset);
1629
1630    DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld\n",
1631            intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
1632
1633}
1634
1635bool venc_dev::venc_reconfig_reqbufs()
1636{
1637    struct v4l2_requestbuffers bufreq;
1638
1639    bufreq.memory = V4L2_MEMORY_USERPTR;
1640    bufreq.count = m_sInput_buff_property.actualcount;
1641    bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1642    if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1643            DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume\n");
1644            return false;
1645    }
1646
1647    bufreq.memory = V4L2_MEMORY_USERPTR;
1648    bufreq.count = m_sOutput_buff_property.actualcount;
1649    bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1650    if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
1651    {
1652            DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed when resume\n");
1653            return false;
1654    }
1655    return true;
1656}
1657
1658unsigned venc_dev::venc_flush( unsigned port)
1659{
1660    struct v4l2_encoder_cmd enc;
1661    DEBUG_PRINT_LOW("in %s", __func__);
1662
1663    enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
1664    enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
1665
1666    if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
1667        DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", port);
1668        return -1;
1669    }
1670
1671    return 0;
1672
1673}
1674
1675//allocating I/P memory from pmem and register with the device
1676
1677
1678bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
1679{
1680
1681    struct pmem *pmem_tmp;
1682    struct v4l2_buffer buf;
1683    struct v4l2_plane plane[VIDEO_MAX_PLANES];
1684    int rc = 0, extra_idx;
1685
1686    pmem_tmp = (struct pmem *)buf_addr;
1687    DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
1688
1689    if (port == PORT_INDEX_IN) {
1690        buf.index = index;
1691        buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1692        buf.memory = V4L2_MEMORY_USERPTR;
1693        plane[0].length = pmem_tmp->size;
1694        plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
1695        plane[0].reserved[0] = pmem_tmp->fd;
1696        plane[0].reserved[1] = 0;
1697        plane[0].data_offset = pmem_tmp->offset;
1698        buf.m.planes = plane;
1699        buf.length = 1;
1700
1701        rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
1702
1703        if (rc)
1704            DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n");
1705    } else if (port == PORT_INDEX_OUT) {
1706        extra_idx = EXTRADATA_IDX(num_planes);
1707
1708        if ((num_planes > 1) && (extra_idx)) {
1709            rc = allocate_extradata();
1710
1711            if (rc)
1712                DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc);
1713        }
1714
1715        buf.index = index;
1716        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1717        buf.memory = V4L2_MEMORY_USERPTR;
1718        plane[0].length = pmem_tmp->size;
1719        plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
1720        plane[0].reserved[0] = pmem_tmp->fd;
1721        plane[0].reserved[1] = 0;
1722        plane[0].data_offset = pmem_tmp->offset;
1723        buf.m.planes = plane;
1724        buf.length = num_planes;
1725
1726        if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1727            plane[extra_idx].length = extradata_info.buffer_size;
1728            plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
1729#ifdef USE_ION
1730            plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
1731#endif
1732            plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
1733            plane[extra_idx].data_offset = 0;
1734        } else if  (extra_idx >= VIDEO_MAX_PLANES) {
1735            DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
1736            return OMX_ErrorBadParameter;
1737        }
1738
1739        rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
1740
1741        if (rc)
1742            DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n");
1743    } else {
1744        DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
1745        return false;
1746    }
1747
1748    return true;
1749}
1750
1751bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
1752{
1753    struct pmem *pmem_tmp;
1754    struct venc_bufferpayload dev_buffer;
1755
1756    memset(&dev_buffer, 0, sizeof(dev_buffer));
1757    pmem_tmp = (struct pmem *)buf_addr;
1758
1759    if (port == PORT_INDEX_IN) {
1760        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1761        dev_buffer.fd  = pmem_tmp->fd;
1762        dev_buffer.maped_size = pmem_tmp->size;
1763        dev_buffer.sz = pmem_tmp->size;
1764        dev_buffer.offset = pmem_tmp->offset;
1765        DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1766                dev_buffer.pbuffer, \
1767                dev_buffer.fd, \
1768                dev_buffer.offset, \
1769                dev_buffer.maped_size);
1770
1771    } else if (port == PORT_INDEX_OUT) {
1772        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1773        dev_buffer.fd  = pmem_tmp->fd;
1774        dev_buffer.sz = pmem_tmp->size;
1775        dev_buffer.maped_size = pmem_tmp->size;
1776        dev_buffer.offset = pmem_tmp->offset;
1777
1778        DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1779                dev_buffer.pbuffer, \
1780                dev_buffer.fd, \
1781                dev_buffer.offset, \
1782                dev_buffer.maped_size);
1783    } else {
1784        DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
1785        return false;
1786    }
1787
1788    return true;
1789}
1790
1791bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
1792        OMX_U32 width, OMX_U32 height)
1793{
1794    OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
1795            y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
1796            uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
1797            uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
1798            src_chroma_offset = width * height;
1799
1800    if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
1801        OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
1802        //Do chroma first, so that we can convert it in-place
1803        src_buf += width * height;
1804        dst_buf += y_stride * y_scanlines;
1805        for (int line = height / 2 - 1; line >= 0; --line) {
1806            memmove(dst_buf + line * uv_stride,
1807                    src_buf + line * width,
1808                    width);
1809        }
1810
1811        dst_buf = src_buf = buffer->pBuffer;
1812        //Copy the Y next
1813        for (int line = height - 1; line > 0; --line) {
1814            memmove(dst_buf + line * y_stride,
1815                    src_buf + line * width,
1816                    width);
1817        }
1818    } else {
1819        DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
1820                Insufficient bufferLen=%u v/s Required=%u",
1821                (width*height), src_chroma_offset, buffer->nAllocLen,
1822                VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
1823        return false;
1824    }
1825
1826    return true;
1827}
1828
1829bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
1830{
1831    struct pmem *temp_buffer;
1832    struct v4l2_buffer buf;
1833    struct v4l2_plane plane;
1834    int rc=0;
1835    struct OMX_BUFFERHEADERTYPE *bufhdr;
1836    encoder_media_buffer_type * meta_buf = NULL;
1837    temp_buffer = (struct pmem *)buffer;
1838
1839    memset (&buf, 0, sizeof(buf));
1840    memset (&plane, 0, sizeof(plane));
1841
1842    if (buffer == NULL) {
1843        DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
1844        return false;
1845    }
1846
1847    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1848
1849    DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
1850
1851    if (pmem_data_buf) {
1852        DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
1853        plane.m.userptr = (unsigned long)pmem_data_buf;
1854        plane.data_offset = bufhdr->nOffset;
1855        plane.length = bufhdr->nAllocLen;
1856        plane.bytesused = bufhdr->nFilledLen;
1857    } else {
1858        // --------------------------------------------------------------------------------------
1859        // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
1860        // ---------------------------------------------------------------------------------------
1861        // Camera-2              1            CameraSource   0              meta-handle
1862        // Camera-3              1            GrallocSource  0              gralloc-private-handle
1863        // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
1864        // CPU (Eg: MediaCodec)  0            --             0              bufhdr
1865        // ---------------------------------------------------------------------------------------
1866        if (metadatamode) {
1867            plane.m.userptr = index;
1868            meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
1869
1870            if (!meta_buf) {
1871                //empty EOS buffer
1872                if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
1873                    plane.data_offset = bufhdr->nOffset;
1874                    plane.length = bufhdr->nAllocLen;
1875                    plane.bytesused = bufhdr->nFilledLen;
1876                    DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
1877                } else {
1878                    return false;
1879                }
1880            } else if (!color_format) {
1881                if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
1882                    plane.data_offset = meta_buf->meta_handle->data[1];
1883                    plane.length = meta_buf->meta_handle->data[2];
1884                    plane.bytesused = meta_buf->meta_handle->data[2];
1885                    DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d",
1886                            fd, plane.bytesused, plane.length);
1887                } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
1888                    private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
1889                    fd = handle->fd;
1890                    plane.data_offset = 0;
1891                    plane.length = handle->size;
1892                    plane.bytesused = handle->size;
1893                        DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
1894                                ": filled %d of %d", fd, plane.bytesused, plane.length);
1895                }
1896            } else {
1897                plane.data_offset = bufhdr->nOffset;
1898                plane.length = bufhdr->nAllocLen;
1899                plane.bytesused = bufhdr->nFilledLen;
1900                DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
1901                        ": filled %d of %d", fd, plane.bytesused, plane.length);
1902            }
1903        } else {
1904            plane.data_offset = bufhdr->nOffset;
1905            plane.length = bufhdr->nAllocLen;
1906            plane.bytesused = bufhdr->nFilledLen;
1907            DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
1908                    fd, plane.bytesused, plane.length);
1909        }
1910    }
1911
1912    buf.index = index;
1913    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1914    buf.memory = V4L2_MEMORY_USERPTR;
1915    plane.reserved[0] = fd;
1916    plane.reserved[1] = 0;
1917    buf.m.planes = &plane;
1918    buf.length = 1;
1919
1920    if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
1921        buf.flags = V4L2_BUF_FLAG_EOS;
1922
1923    buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
1924    buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
1925    rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
1926
1927    if (rc) {
1928        DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
1929        return false;
1930    }
1931
1932    etb++;
1933
1934    if (!streaming[OUTPUT_PORT]) {
1935        enum v4l2_buf_type buf_type;
1936        buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1937        int ret;
1938        ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
1939
1940        if (ret) {
1941            DEBUG_PRINT_ERROR("Failed to call streamon\n");
1942            return false;
1943        } else {
1944            streaming[OUTPUT_PORT] = true;
1945        }
1946    }
1947
1948#ifdef INPUT_BUFFER_LOG
1949    int i;
1950    int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
1951    int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
1952    char *temp = (char *)bufhdr->pBuffer;
1953
1954    for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1955        fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1);
1956        temp += stride;
1957    }
1958
1959    temp = (char *)bufhdr->pBuffer + (stride * scanlines);
1960
1961    for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
1962        fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1);
1963        temp += stride;
1964    }
1965
1966#endif
1967    return true;
1968}
1969bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
1970{
1971    struct pmem *temp_buffer = NULL;
1972    struct venc_buffer  frameinfo;
1973    struct v4l2_buffer buf;
1974    struct v4l2_plane plane[VIDEO_MAX_PLANES];
1975    int rc = 0, extra_idx;
1976    struct OMX_BUFFERHEADERTYPE *bufhdr;
1977
1978    if (buffer == NULL)
1979        return false;
1980
1981    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1982
1983    if (pmem_data_buf) {
1984        DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
1985        plane[0].m.userptr = (unsigned long)pmem_data_buf;
1986    } else {
1987        DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1988        plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
1989    }
1990
1991    buf.index = index;
1992    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1993    buf.memory = V4L2_MEMORY_USERPTR;
1994    plane[0].length = bufhdr->nAllocLen;
1995    plane[0].bytesused = bufhdr->nFilledLen;
1996    plane[0].reserved[0] = fd;
1997    plane[0].reserved[1] = 0;
1998    plane[0].data_offset = bufhdr->nOffset;
1999    buf.m.planes = plane;
2000    buf.length = num_planes;
2001
2002    extra_idx = EXTRADATA_IDX(num_planes);
2003
2004    if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2005        plane[extra_idx].bytesused = 0;
2006        plane[extra_idx].length = extradata_info.buffer_size;
2007        plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2008#ifdef USE_ION
2009        plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2010#endif
2011        plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2012        plane[extra_idx].data_offset = 0;
2013    } else if (extra_idx >= VIDEO_MAX_PLANES) {
2014        DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
2015        return false;
2016    }
2017
2018    rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2019
2020    if (rc) {
2021        DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
2022        return false;
2023    }
2024
2025    ftb++;
2026    return true;
2027}
2028
2029bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
2030{
2031    struct v4l2_control control;
2032    control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2033    control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
2034    DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
2035
2036    if (multislice.mslice_mode && multislice.mslice_mode != V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
2037        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2038            DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
2039            return false;
2040        }
2041    } else {
2042        DEBUG_PRINT_ERROR("Failed to set slice extradata, slice_mode "
2043                "is set to [%lu]", multislice.mslice_mode);
2044    }
2045
2046    return true;
2047}
2048
2049bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
2050{
2051    struct v4l2_control control;
2052
2053    if (enable) {
2054        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
2055        control.value = 1;
2056        DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
2057
2058        if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2059            if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2060                DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
2061                return false;
2062            } else {
2063                DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d\n", control.id, control.value);
2064                slice_mode.enable = 1;
2065            }
2066        } else {
2067            DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%d] "
2068                    "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
2069                    m_sVenc_cfg.codectype);
2070        }
2071    } else {
2072        DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled\n");
2073    }
2074
2075    return true;
2076}
2077
2078bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
2079{
2080    int rc;
2081    struct v4l2_control control;
2082
2083    control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
2084    control.value = i_frame_qp;
2085
2086    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2087    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2088
2089    if (rc) {
2090        DEBUG_PRINT_ERROR("Failed to set control\n");
2091        return false;
2092    }
2093
2094    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2095    session_qp.iframeqp = control.value;
2096
2097    control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
2098    control.value = p_frame_qp;
2099
2100    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2101    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2102
2103    if (rc) {
2104        DEBUG_PRINT_ERROR("Failed to set control\n");
2105        return false;
2106    }
2107
2108    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2109
2110    session_qp.pframqp = control.value;
2111
2112    if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
2113            (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
2114
2115        control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
2116        control.value = b_frame_qp;
2117
2118        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2119        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2120
2121        if (rc) {
2122            DEBUG_PRINT_ERROR("Failed to set control\n");
2123            return false;
2124        }
2125
2126        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2127
2128        session_qp.bframqp = control.value;
2129    }
2130
2131    return true;
2132}
2133
2134bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
2135{
2136    struct venc_profile requested_profile = {0};
2137    struct ven_profilelevel requested_level = {0};
2138    unsigned long mb_per_frame = 0;
2139    DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d",
2140            eProfile, eLevel);
2141    mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
2142        ((m_sVenc_cfg.input_width + 15) >> 4);
2143
2144    if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
2145        DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start");
2146        return true;
2147    }
2148
2149    DEBUG_PRINT_LOW("\n Validating Profile/Level from table");
2150
2151    if (!venc_validate_profile_level(&eProfile, &eLevel)) {
2152        DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
2153        return false;
2154    }
2155
2156    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2157        DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
2158                "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
2159                OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
2160
2161        if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
2162            requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
2163        } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
2164            requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
2165        } else {
2166            DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
2167                    eProfile);
2168            return false;
2169        }
2170
2171        DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
2172                "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
2173                "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
2174                OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
2175
2176        if (mb_per_frame >= 3600) {
2177            if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
2178                requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2179
2180            if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
2181                requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2182        } else {
2183            switch (eLevel) {
2184                case OMX_VIDEO_MPEG4Level0:
2185                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
2186                    break;
2187                case OMX_VIDEO_MPEG4Level0b:
2188                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
2189                    break;
2190                case OMX_VIDEO_MPEG4Level1:
2191                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
2192                    break;
2193                case OMX_VIDEO_MPEG4Level2:
2194                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
2195                    break;
2196                case OMX_VIDEO_MPEG4Level3:
2197                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
2198                    break;
2199                case OMX_VIDEO_MPEG4Level4a:
2200                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
2201                    break;
2202                case OMX_VIDEO_MPEG4Level5:
2203                    requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2204                    break;
2205                default:
2206                    return false;
2207                    // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
2208                    break;
2209            }
2210        }
2211    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
2212
2213        switch (eProfile) {
2214            case OMX_VIDEO_H263ProfileBaseline:
2215                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
2216                break;
2217            case OMX_VIDEO_H263ProfileH320Coding:
2218                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
2219                break;
2220            case OMX_VIDEO_H263ProfileBackwardCompatible:
2221                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
2222                break;
2223            case OMX_VIDEO_H263ProfileISWV2:
2224                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
2225                break;
2226            case OMX_VIDEO_H263ProfileISWV3:
2227                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
2228                break;
2229            case OMX_VIDEO_H263ProfileHighCompression:
2230                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
2231                break;
2232            case OMX_VIDEO_H263ProfileInternet:
2233                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
2234                break;
2235            case OMX_VIDEO_H263ProfileInterlace:
2236                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
2237                break;
2238            case OMX_VIDEO_H263ProfileHighLatency:
2239                requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
2240                break;
2241            default:
2242                DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
2243                        requested_profile.profile);
2244                return false;
2245        }
2246
2247        //profile level
2248        switch (eLevel) {
2249            case OMX_VIDEO_H263Level10:
2250                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
2251                break;
2252            case OMX_VIDEO_H263Level20:
2253                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
2254                break;
2255            case OMX_VIDEO_H263Level30:
2256                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
2257                break;
2258            case OMX_VIDEO_H263Level40:
2259                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
2260                break;
2261            case OMX_VIDEO_H263Level45:
2262                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
2263                break;
2264            case OMX_VIDEO_H263Level50:
2265                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
2266                break;
2267            case OMX_VIDEO_H263Level60:
2268                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
2269                break;
2270            case OMX_VIDEO_H263Level70:
2271                requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
2272                break;
2273            default:
2274                return false;
2275                break;
2276        }
2277    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2278        if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
2279            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
2280        } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
2281            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
2282        } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
2283            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
2284        } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
2285            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
2286        } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
2287            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
2288        } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
2289            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
2290        } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
2291            requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
2292        } else {
2293            DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
2294                    requested_profile.profile);
2295            return false;
2296        }
2297
2298        //profile level
2299        switch (eLevel) {
2300            case OMX_VIDEO_AVCLevel1:
2301                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
2302                break;
2303            case OMX_VIDEO_AVCLevel1b:
2304                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
2305                break;
2306            case OMX_VIDEO_AVCLevel11:
2307                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
2308                break;
2309            case OMX_VIDEO_AVCLevel12:
2310                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
2311                break;
2312            case OMX_VIDEO_AVCLevel13:
2313                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
2314                break;
2315            case OMX_VIDEO_AVCLevel2:
2316                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
2317                break;
2318            case OMX_VIDEO_AVCLevel21:
2319                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
2320                break;
2321            case OMX_VIDEO_AVCLevel22:
2322                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
2323                break;
2324            case OMX_VIDEO_AVCLevel3:
2325                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
2326                break;
2327            case OMX_VIDEO_AVCLevel31:
2328                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
2329                break;
2330            case OMX_VIDEO_AVCLevel32:
2331                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
2332                break;
2333            case OMX_VIDEO_AVCLevel4:
2334                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
2335                break;
2336            case OMX_VIDEO_AVCLevel41:
2337                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
2338                break;
2339            case OMX_VIDEO_AVCLevel42:
2340                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
2341                break;
2342            case OMX_VIDEO_AVCLevel5:
2343                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
2344                break;
2345            case OMX_VIDEO_AVCLevel51:
2346                requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
2347                break;
2348            default :
2349                DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %lu",
2350                        requested_level.level);
2351                return false;
2352                break;
2353        }
2354    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
2355        if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
2356            DEBUG_PRINT_ERROR("\nERROR: Unsupported VP8 profile = %u",
2357                        eProfile);
2358            return false;
2359        }
2360        requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
2361        m_profile_set = true;
2362        switch(eLevel) {
2363            case OMX_VIDEO_VP8Level_Version0:
2364                requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
2365                break;
2366            case OMX_VIDEO_VP8Level_Version1:
2367                requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
2368                break;
2369            default:
2370                DEBUG_PRINT_ERROR("\nERROR: Unsupported VP8 level= %lu",
2371                            eLevel);
2372                return false;
2373                break;
2374        }
2375    }
2376
2377    if (!m_profile_set) {
2378        int rc;
2379        struct v4l2_control control;
2380
2381        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2382            control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
2383        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2384            control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
2385        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
2386            control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
2387        } else {
2388            DEBUG_PRINT_ERROR("\n Wrong CODEC \n");
2389            return false;
2390        }
2391
2392        control.value = requested_profile.profile;
2393
2394        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2395        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2396
2397        if (rc) {
2398            DEBUG_PRINT_ERROR("Failed to set control\n");
2399            return false;
2400        }
2401
2402        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2403
2404        codec_profile.profile = control.value;
2405        m_profile_set = true;
2406    }
2407
2408    if (!m_level_set) {
2409        int rc;
2410        struct v4l2_control control;
2411
2412        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2413            control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
2414        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2415            control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
2416        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
2417            control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
2418        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
2419            control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
2420        } else {
2421            DEBUG_PRINT_ERROR("\n Wrong CODEC \n");
2422            return false;
2423        }
2424
2425        control.value = requested_level.level;
2426
2427        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2428        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2429
2430        if (rc) {
2431            DEBUG_PRINT_ERROR("Failed to set control\n");
2432            return false;
2433        }
2434
2435        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2436
2437        profile_level.level = control.value;
2438        m_level_set = true;
2439    }
2440
2441    return true;
2442}
2443
2444bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
2445{
2446
2447    struct venc_voptimingcfg vop_timing_cfg;
2448
2449    DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u",
2450            TimeIncRes);
2451
2452    vop_timing_cfg.voptime_resolution = TimeIncRes;
2453
2454    voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
2455    return true;
2456}
2457
2458bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
2459{
2460
2461    DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u",
2462            nPFrames);
2463    int rc;
2464    struct v4l2_control control;
2465
2466    if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
2467            (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
2468            (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
2469        nBFrames=0;
2470    }
2471
2472    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
2473    control.value = nPFrames;
2474
2475    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2476
2477    if (rc) {
2478        DEBUG_PRINT_ERROR("Failed to set control\n");
2479        return false;
2480    }
2481
2482    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2483
2484    intra_period.num_pframes = control.value;
2485    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
2486    control.value = nBFrames;
2487    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2488    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2489
2490    if (rc) {
2491        DEBUG_PRINT_ERROR("Failed to set control\n");
2492        return false;
2493    }
2494
2495    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2496
2497
2498    intra_period.num_bframes = control.value;
2499
2500    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2501        control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2502        control.value = 1;
2503
2504        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2505
2506        if (rc) {
2507            DEBUG_PRINT_ERROR("Failed to set control\n");
2508            return false;
2509        }
2510
2511        idrperiod.idrperiod = 1;
2512    }
2513
2514    return true;
2515}
2516
2517bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
2518{
2519    int rc = 0;
2520    struct v4l2_control control;
2521    DEBUG_PRINT_LOW("\n venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u\n",
2522            nPFrames, nIDRPeriod);
2523
2524    if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
2525        DEBUG_PRINT_ERROR("\nERROR: IDR period valid for H264 only!!");
2526        return false;
2527    }
2528
2529    if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
2530        DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
2531        return false;
2532    }
2533
2534    intra_period.num_pframes = nPFrames;
2535    control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2536    control.value = nIDRPeriod;
2537
2538    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2539
2540    if (rc) {
2541        DEBUG_PRINT_ERROR("Failed to set control\n");
2542        return false;
2543    }
2544
2545    idrperiod.idrperiod = nIDRPeriod;
2546    return true;
2547}
2548
2549bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
2550{
2551    int rc = 0;
2552    struct v4l2_control control;
2553
2554    DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
2555
2556    if (enable &&(codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE)) {
2557
2558        control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
2559        control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
2560
2561        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2562        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2563
2564        if (rc) {
2565            DEBUG_PRINT_ERROR("Failed to set control\n");
2566            return false;
2567        }
2568
2569        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2570        entropy.longentropysel = control.value;
2571
2572        if (i_cabac_level == 0) {
2573            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
2574        } else if (i_cabac_level == 1) {
2575            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
2576        } else if (i_cabac_level == 2) {
2577            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
2578        }
2579
2580        control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
2581        //control.value = entropy_cfg.cabacmodel;
2582        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2583        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2584
2585        if (rc) {
2586            DEBUG_PRINT_ERROR("Failed to set control\n");
2587            return false;
2588        }
2589
2590        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2591        entropy.cabacmodel=control.value;
2592    } else if (!enable) {
2593        control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
2594        control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
2595        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2596        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2597
2598        if (rc) {
2599            DEBUG_PRINT_ERROR("Failed to set control\n");
2600            return false;
2601        }
2602
2603        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2604        entropy.longentropysel=control.value;
2605    } else {
2606        DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
2607        return false;
2608    }
2609
2610    return true;
2611}
2612
2613bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
2614{
2615    int rc;
2616    struct v4l2_control control;
2617    bool status = true;
2618
2619    if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
2620        control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
2621    } else {
2622        control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
2623    }
2624
2625    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
2626    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2627    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2628
2629    if (rc) {
2630        DEBUG_PRINT_ERROR("Failed to set control\n");
2631        return false;
2632    }
2633
2634    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2635    multislice.mslice_mode=control.value;
2636
2637    if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
2638
2639        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
2640        control.value = nSlicesize;
2641        DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2642        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2643
2644        if (rc) {
2645            DEBUG_PRINT_ERROR("Failed to set control\n");
2646            return false;
2647        }
2648
2649        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2650        multislice.mslice_size=control.value;
2651
2652    }
2653
2654    return status;
2655}
2656
2657bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
2658{
2659    bool status = true;
2660    int rc;
2661    struct v4l2_control control_mode,control_mbs;
2662    control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
2663
2664    // There is no disabled mode.  Disabled mode is indicated by a 0 count.
2665    if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
2666        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
2667        return status;
2668    } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
2669            (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) {
2670        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
2671        control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
2672        control_mbs.value=irMBs;
2673    } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
2674            (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) {
2675        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
2676        control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
2677        control_mbs.value=irMBs;
2678    } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
2679            (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) {
2680        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
2681    } else {
2682        DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
2683                "mb count: %lu, mb mode:%d", irMBs, ir_mode);
2684        return false;
2685    }
2686
2687    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%lu, val=%lu\n", control_mode.id, control_mode.value);
2688    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
2689
2690    if (rc) {
2691        DEBUG_PRINT_ERROR("Failed to set control\n");
2692        return false;
2693    }
2694
2695    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mode.id, control_mode.value);
2696
2697    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control_mbs.id, control_mbs.value);
2698    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
2699
2700    if (rc) {
2701        DEBUG_PRINT_ERROR("Failed to set control\n");
2702        return false;
2703    }
2704
2705    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mbs.id, control_mbs.value);
2706
2707    intra_refresh.irmode = control_mode.value;
2708    intra_refresh.mbcount = control_mbs.value;
2709
2710    return status;
2711}
2712
2713bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
2714{
2715    bool status = true;
2716    struct venc_headerextension hec_cfg;
2717    struct venc_multiclicecfg multislice_cfg;
2718    int rc;
2719    struct v4l2_control control;
2720
2721    memset(&control, 0, sizeof(control));
2722
2723    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2724        if (error_resilience->bEnableHEC) {
2725            hec_cfg.header_extension = 1;
2726        } else {
2727            hec_cfg.header_extension = 0;
2728        }
2729
2730        hec.header_extension = error_resilience->bEnableHEC;
2731    }
2732
2733    if (error_resilience->bEnableRVLC) {
2734        DEBUG_PRINT_ERROR("\n RVLC is not Supported");
2735        return false;
2736    }
2737
2738    if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
2739            (error_resilience->bEnableDataPartitioning)) {
2740        DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
2741        return false;
2742    }
2743
2744    if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
2745            (error_resilience->nResynchMarkerSpacing)) {
2746        multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
2747        multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
2748        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
2749        control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
2750    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
2751            error_resilience->bEnableDataPartitioning) {
2752        multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
2753        multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
2754        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
2755        control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
2756    } else {
2757        multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
2758        multislice_cfg.mslice_size = 0;
2759        control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
2760        control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
2761    }
2762
2763    DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__,
2764            multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
2765    printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value);
2766    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2767
2768    if (rc) {
2769        printf("Failed to set Slice mode control\n");
2770        return false;
2771    }
2772
2773    printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value);
2774    multislice.mslice_mode=control.value;
2775
2776    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
2777    control.value = error_resilience->nResynchMarkerSpacing;
2778    printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value);
2779    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2780
2781    if (rc) {
2782        printf("Failed to set MAX MB control\n");
2783        return false;
2784    }
2785
2786    printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value);
2787    multislice.mslice_mode = multislice_cfg.mslice_mode;
2788    multislice.mslice_size = multislice_cfg.mslice_size;
2789    return status;
2790}
2791
2792bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
2793{
2794    int rc;
2795    struct v4l2_control control;
2796    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
2797
2798    if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
2799        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
2800    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
2801        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
2802    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
2803        control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
2804    }
2805
2806    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2807    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2808
2809    if (rc) {
2810        return false;
2811    }
2812
2813    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2814
2815    dbkfilter.db_mode=control.value;
2816
2817    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
2818    control.value=0;
2819
2820    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2821    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2822
2823    if (rc) {
2824        return false;
2825    }
2826
2827    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2828    control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
2829    control.value=0;
2830    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2831    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2832
2833    if (rc) {
2834        return false;
2835    }
2836
2837    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2838
2839
2840    dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
2841    return true;
2842}
2843
2844bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
2845{
2846    DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u",
2847            nTargetBitrate);
2848    struct v4l2_control control;
2849    int rc = 0;
2850    control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
2851    control.value = nTargetBitrate;
2852
2853    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2854    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2855
2856    if (rc) {
2857        DEBUG_PRINT_ERROR("Failed to set control\n");
2858        return false;
2859    }
2860
2861    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
2862
2863
2864    m_sVenc_cfg.targetbitrate = control.value;
2865    bitrate.target_bitrate = control.value;
2866
2867    if (!config) {
2868        m_level_set = false;
2869
2870        if (venc_set_profile_level(0, 0)) {
2871            DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu\n",profile_level.level);
2872        }
2873    }
2874
2875    return true;
2876}
2877
2878bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
2879{
2880    struct v4l2_streamparm parm;
2881    int rc = 0;
2882    struct venc_framerate frame_rate_cfg;
2883    Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
2884    parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2885    parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
2886    parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
2887
2888    if (frame_rate_cfg.fps_numerator > 0)
2889        rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
2890
2891    if (rc) {
2892        DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed\n");
2893        return false;
2894    }
2895
2896    m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
2897    m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
2898
2899    if (!config) {
2900        m_level_set = false;
2901
2902        if (venc_set_profile_level(0, 0)) {
2903            DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu\n",profile_level.level);
2904        }
2905    }
2906
2907    return true;
2908}
2909
2910bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
2911{
2912    struct v4l2_format fmt;
2913    DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format);
2914
2915    if (color_format == OMX_COLOR_FormatYUV420SemiPlanar ||
2916            color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
2917        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
2918    } else if (color_format == QOMX_COLOR_FormatYVU420SemiPlanar) {
2919        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
2920    } else {
2921        DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
2922        m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
2923        DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
2924    }
2925
2926    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2927    fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
2928    fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
2929    fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
2930
2931    if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
2932        DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
2933        return false;
2934    }
2935
2936    return true;
2937}
2938
2939bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
2940{
2941    DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
2942
2943    if (intra_vop_refresh == OMX_TRUE) {
2944        struct v4l2_control control;
2945        int rc;
2946        control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
2947        control.value = 1;
2948        printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value);
2949        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2950
2951        if (rc) {
2952            printf("Failed to set Intra Frame Request control\n");
2953            return false;
2954        }
2955
2956        printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value);
2957    } else {
2958        DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
2959    }
2960
2961    return true;
2962}
2963
2964bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
2965{
2966    bool status = true;
2967    struct v4l2_control control;
2968    int rc = 0;
2969    control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
2970
2971    switch (eControlRate) {
2972        case OMX_Video_ControlRateDisable:
2973            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
2974            break;
2975        case OMX_Video_ControlRateVariableSkipFrames:
2976            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
2977            break;
2978        case OMX_Video_ControlRateVariable:
2979            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
2980            break;
2981        case OMX_Video_ControlRateConstantSkipFrames:
2982            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
2983            break;
2984        case OMX_Video_ControlRateConstant:
2985            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
2986            break;
2987        default:
2988            status = false;
2989            break;
2990    }
2991
2992    if (status) {
2993
2994        DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
2995        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2996
2997        if (rc) {
2998            DEBUG_PRINT_ERROR("Failed to set control\n");
2999            return false;
3000        }
3001
3002        DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
3003
3004        rate_ctrl.rcmode = control.value;
3005    }
3006
3007    return status;
3008}
3009
3010bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
3011{
3012    bool status = true;
3013
3014    if (eProfile == NULL || eLevel == NULL) {
3015        return false;
3016    }
3017
3018    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3019        switch (codec_profile.profile) {
3020            case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
3021                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
3022                break;
3023            case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
3024                *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
3025                break;
3026            default:
3027                *eProfile = OMX_VIDEO_MPEG4ProfileMax;
3028                status = false;
3029                break;
3030        }
3031
3032        if (!status) {
3033            return status;
3034        }
3035
3036        //profile level
3037        switch (profile_level.level) {
3038            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
3039                *eLevel = OMX_VIDEO_MPEG4Level0;
3040                break;
3041            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
3042                *eLevel = OMX_VIDEO_MPEG4Level0b;
3043                break;
3044            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
3045                *eLevel = OMX_VIDEO_MPEG4Level1;
3046                break;
3047            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
3048                *eLevel = OMX_VIDEO_MPEG4Level2;
3049                break;
3050            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
3051                *eLevel = OMX_VIDEO_MPEG4Level3;
3052                break;
3053            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
3054                *eLevel = OMX_VIDEO_MPEG4Level4;
3055                break;
3056            case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
3057                *eLevel = OMX_VIDEO_MPEG4Level5;
3058                break;
3059            default:
3060                *eLevel = OMX_VIDEO_MPEG4LevelMax;
3061                status =  false;
3062                break;
3063        }
3064    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3065        if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
3066            *eProfile = OMX_VIDEO_H263ProfileBaseline;
3067        } else {
3068            *eProfile = OMX_VIDEO_H263ProfileMax;
3069            return false;
3070        }
3071
3072        switch (profile_level.level) {
3073            case VEN_LEVEL_H263_10:
3074                *eLevel = OMX_VIDEO_H263Level10;
3075                break;
3076            case VEN_LEVEL_H263_20:
3077                *eLevel = OMX_VIDEO_H263Level20;
3078                break;
3079            case VEN_LEVEL_H263_30:
3080                *eLevel = OMX_VIDEO_H263Level30;
3081                break;
3082            case VEN_LEVEL_H263_40:
3083                *eLevel = OMX_VIDEO_H263Level40;
3084                break;
3085            case VEN_LEVEL_H263_45:
3086                *eLevel = OMX_VIDEO_H263Level45;
3087                break;
3088            case VEN_LEVEL_H263_50:
3089                *eLevel = OMX_VIDEO_H263Level50;
3090                break;
3091            case VEN_LEVEL_H263_60:
3092                *eLevel = OMX_VIDEO_H263Level60;
3093                break;
3094            case VEN_LEVEL_H263_70:
3095                *eLevel = OMX_VIDEO_H263Level70;
3096                break;
3097            default:
3098                *eLevel = OMX_VIDEO_H263LevelMax;
3099                status = false;
3100                break;
3101        }
3102    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3103        switch (codec_profile.profile) {
3104            case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
3105                *eProfile = OMX_VIDEO_AVCProfileBaseline;
3106                break;
3107            case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
3108                *eProfile = OMX_VIDEO_AVCProfileMain;
3109                break;
3110            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
3111                *eProfile = OMX_VIDEO_AVCProfileHigh;
3112                break;
3113            case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
3114                *eProfile = OMX_VIDEO_AVCProfileExtended;
3115                break;
3116            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
3117                *eProfile = OMX_VIDEO_AVCProfileHigh10;
3118                break;
3119            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
3120                *eProfile = OMX_VIDEO_AVCProfileHigh422;
3121                break;
3122            case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
3123                *eProfile = OMX_VIDEO_AVCProfileHigh444;
3124                break;
3125            default:
3126                *eProfile = OMX_VIDEO_AVCProfileMax;
3127                status = false;
3128                break;
3129        }
3130
3131        if (!status) {
3132            return status;
3133        }
3134
3135        switch (profile_level.level) {
3136            case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
3137                *eLevel = OMX_VIDEO_AVCLevel1;
3138                break;
3139            case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
3140                *eLevel = OMX_VIDEO_AVCLevel1b;
3141                break;
3142            case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
3143                *eLevel = OMX_VIDEO_AVCLevel11;
3144                break;
3145            case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
3146                *eLevel = OMX_VIDEO_AVCLevel12;
3147                break;
3148            case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
3149                *eLevel = OMX_VIDEO_AVCLevel13;
3150                break;
3151            case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
3152                *eLevel = OMX_VIDEO_AVCLevel2;
3153                break;
3154            case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
3155                *eLevel = OMX_VIDEO_AVCLevel21;
3156                break;
3157            case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
3158                *eLevel = OMX_VIDEO_AVCLevel22;
3159                break;
3160            case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
3161                *eLevel = OMX_VIDEO_AVCLevel3;
3162                break;
3163            case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
3164                *eLevel = OMX_VIDEO_AVCLevel31;
3165                break;
3166            case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
3167                *eLevel = OMX_VIDEO_AVCLevel32;
3168                break;
3169            case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
3170                *eLevel = OMX_VIDEO_AVCLevel4;
3171                break;
3172            case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
3173                *eLevel = OMX_VIDEO_AVCLevel41;
3174                break;
3175            case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
3176                *eLevel = OMX_VIDEO_AVCLevel42;
3177                break;
3178            case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
3179                *eLevel = OMX_VIDEO_AVCLevel5;
3180                break;
3181            case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
3182                *eLevel = OMX_VIDEO_AVCLevel51;
3183                break;
3184            default :
3185                *eLevel = OMX_VIDEO_AVCLevelMax;
3186                status = false;
3187                break;
3188        }
3189    }
3190    else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3191        switch (codec_profile.profile) {
3192            case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
3193                *eProfile = OMX_VIDEO_VP8ProfileMain;
3194                break;
3195            default:
3196                *eProfile = OMX_VIDEO_VP8ProfileMax;
3197                status = false;
3198                break;
3199        }
3200        if (!status) {
3201            return status;
3202        }
3203
3204        switch (profile_level.level) {
3205            case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
3206                *eLevel = OMX_VIDEO_VP8Level_Version0;
3207                break;
3208            case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
3209                *eLevel = OMX_VIDEO_VP8Level_Version1;
3210                break;
3211            default:
3212                *eLevel = OMX_VIDEO_VP8LevelMax;
3213                status = false;
3214                break;
3215        }
3216    }
3217
3218    return status;
3219}
3220
3221bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
3222{
3223    OMX_U32 new_profile = 0, new_level = 0;
3224    unsigned const int *profile_tbl = NULL;
3225    OMX_U32 mb_per_frame, mb_per_sec;
3226    bool profile_level_found = false;
3227
3228    DEBUG_PRINT_LOW("\n Init profile table for respective codec");
3229
3230    //validate the ht,width,fps,bitrate and set the appropriate profile and level
3231    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3232        if (*eProfile == 0) {
3233            if (!m_profile_set) {
3234                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
3235            } else {
3236                switch (codec_profile.profile) {
3237                    case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
3238                        *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
3239                        break;
3240                    case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
3241                        *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
3242                        break;
3243                    default:
3244                        DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
3245                        return false;
3246                }
3247            }
3248        }
3249
3250        if (*eLevel == 0 && !m_level_set) {
3251            *eLevel = OMX_VIDEO_MPEG4LevelMax;
3252        }
3253
3254        if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
3255            profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
3256        } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
3257            profile_tbl = (unsigned int const *)
3258                (&mpeg4_profile_level_table[MPEG4_ASP_START]);
3259        } else {
3260            DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
3261            return false;
3262        }
3263    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3264        if (*eProfile == 0) {
3265            if (!m_profile_set) {
3266                *eProfile = OMX_VIDEO_AVCProfileBaseline;
3267            } else {
3268                switch (codec_profile.profile) {
3269                    case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
3270                        *eProfile = OMX_VIDEO_AVCProfileBaseline;
3271                        break;
3272                    case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
3273                        *eProfile = OMX_VIDEO_AVCProfileMain;
3274                        break;
3275                    case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
3276                        *eProfile = OMX_VIDEO_AVCProfileExtended;
3277                        break;
3278                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
3279                        *eProfile = OMX_VIDEO_AVCProfileHigh;
3280                        break;
3281                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
3282                        *eProfile = OMX_VIDEO_AVCProfileHigh10;
3283                        break;
3284                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
3285                        *eProfile = OMX_VIDEO_AVCProfileHigh422;
3286                        break;
3287                    case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
3288                        *eProfile = OMX_VIDEO_AVCProfileHigh444;
3289                        break;
3290                    default:
3291                        DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
3292                        return false;
3293                }
3294            }
3295        }
3296
3297        if (*eLevel == 0 && !m_level_set) {
3298            *eLevel = OMX_VIDEO_AVCLevelMax;
3299        }
3300
3301        if (*eProfile == OMX_VIDEO_AVCProfileBaseline) {
3302            profile_tbl = (unsigned int const *)h264_profile_level_table;
3303        } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
3304            profile_tbl = (unsigned int const *)
3305                (&h264_profile_level_table[H264_HP_START]);
3306        } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
3307            profile_tbl = (unsigned int const *)
3308                (&h264_profile_level_table[H264_MP_START]);
3309        } else {
3310            DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
3311            return false;
3312        }
3313    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3314        if (*eProfile == 0) {
3315            if (!m_profile_set) {
3316                *eProfile = OMX_VIDEO_H263ProfileBaseline;
3317            } else {
3318                switch (codec_profile.profile) {
3319                    case VEN_PROFILE_H263_BASELINE:
3320                        *eProfile = OMX_VIDEO_H263ProfileBaseline;
3321                        break;
3322                    default:
3323                        DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
3324                        return false;
3325                }
3326            }
3327        }
3328
3329        if (*eLevel == 0 && !m_level_set) {
3330            *eLevel = OMX_VIDEO_H263LevelMax;
3331        }
3332
3333        if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
3334            profile_tbl = (unsigned int const *)h263_profile_level_table;
3335        } else {
3336            DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
3337            return false;
3338        }
3339    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3340        if (*eProfile == 0) {
3341            *eProfile = OMX_VIDEO_VP8ProfileMain;
3342        } else {
3343            switch (codec_profile.profile) {
3344                case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
3345                    *eProfile = OMX_VIDEO_VP8ProfileMain;
3346                    break;
3347                default:
3348                    DEBUG_PRINT_ERROR("\n %s(): Unknown VP8 profile", __func__);
3349                    return false;
3350            }
3351        }
3352        if (*eLevel == 0) {
3353            switch (profile_level.level) {
3354                case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
3355                    *eLevel = OMX_VIDEO_VP8Level_Version0;
3356                    break;
3357                case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
3358                    *eLevel = OMX_VIDEO_VP8Level_Version1;
3359                    break;
3360                default:
3361                    DEBUG_PRINT_ERROR("\n %s(): Unknown VP8 level", __func__);
3362                    return false;
3363            }
3364        }
3365        return true;
3366    } else {
3367        DEBUG_PRINT_LOW("\n Invalid codec type");
3368        return false;
3369    }
3370
3371    mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
3372        ((m_sVenc_cfg.input_width + 15)>> 4);
3373
3374    if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
3375        if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
3376            profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3377
3378        if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
3379            profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3380
3381        {
3382            new_level = profile_level.level;
3383            new_profile = codec_profile.profile;
3384            return true;
3385        }
3386    }
3387
3388    mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
3389
3390    do {
3391        if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
3392            if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
3393                if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
3394                    new_level = (int)profile_tbl[3];
3395                    new_profile = (int)profile_tbl[4];
3396                    profile_level_found = true;
3397                    DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
3398                    break;
3399                }
3400            }
3401        }
3402
3403        profile_tbl = profile_tbl + 5;
3404    } while (profile_tbl[0] != 0);
3405
3406    if (profile_level_found != true) {
3407        DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
3408        return false;
3409    }
3410
3411    if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
3412            || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) {
3413        *eLevel = new_level;
3414    }
3415
3416    DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu\n"
3417            "Level = %lu", __func__, *eProfile, *eLevel);
3418
3419    return true;
3420}
3421#ifdef _ANDROID_ICS_
3422bool venc_dev::venc_set_meta_mode(bool mode)
3423{
3424    metadatamode = 1;
3425    return true;
3426}
3427#endif
3428
3429bool venc_dev::venc_is_video_session_supported(unsigned long width,
3430        unsigned long height)
3431{
3432    if ((width * height < capability.min_width *  capability.min_height) ||
3433            (width * height > capability.max_width *  capability.max_height)) {
3434        DEBUG_PRINT_ERROR(
3435                "Unsupported video resolution WxH = (%d)x(%d) supported range = min (%d)x(%d) - max (%d)x(%d)\n",
3436                width, height, capability.min_width, capability.min_height,
3437                capability.max_width, capability.max_height);
3438        return false;
3439    }
3440
3441    DEBUG_PRINT_LOW("\n video session supported\n");
3442    return true;
3443}
3444