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#include<string.h>
29#include <sys/ioctl.h>
30#include <sys/prctl.h>
31#include<unistd.h>
32#include <fcntl.h>
33#include "video_encoder_device.h"
34#include "omx_video_encoder.h"
35#include <linux/android_pmem.h>
36#ifdef USE_ION
37#include <linux/msm_ion.h>
38#endif
39
40#define MPEG4_SP_START 0
41#define MPEG4_ASP_START (MPEG4_SP_START + 8)
42#define MPEG4_720P_LEVEL 6
43#define H263_BP_START 0
44#define H264_BP_START 0
45#define H264_HP_START (H264_BP_START + 13)
46#define H264_MP_START (H264_BP_START + 26)
47
48/* MPEG4 profile and level table*/
49static const unsigned int mpeg4_profile_level_table[][5]= {
50    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
51    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
52    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
53    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
54    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
55    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
56    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
57    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
58    {0,0,0,0,0},
59
60    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
61    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
62    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
63    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
64    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
65    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
66    {0,0,0,0,0},
67};
68
69/* H264 profile and level table*/
70static const unsigned int h264_profile_level_table[][5]= {
71    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
72    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
73    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
74    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
75    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
76    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
77    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
78    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
79    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
80    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
81    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
82    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
83    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
84    {0,0,0,0,0},
85
86    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
87    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
88    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
89    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
90    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
91    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
92    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
93    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
94    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
95    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
96    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
97    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
98    {0,0,0,0,0},
99
100    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
101    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
102    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
103    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
104    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
105    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
106    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
107    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
108    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
109    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
110    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
111    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
112    {0,0,0,0,0}
113
114};
115
116/* H263 profile and level table*/
117static const unsigned int h263_profile_level_table[][5]= {
118    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
119    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
120    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
121    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
122    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
123    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
124    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
125    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
126    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
127    {0,0,0,0,0}
128};
129
130#define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
131#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
132
133#define BUFFER_LOG_LOC "/data/misc/media"
134
135//constructor
136venc_dev::venc_dev(class omx_venc *venc_class)
137{
138    m_max_allowed_bitrate_check = false;
139    m_eLevel = 0;
140    m_eProfile = 0;
141    pthread_mutex_init(&loaded_start_stop_mlock, NULL);
142    pthread_cond_init (&loaded_start_stop_cond, NULL);
143    memset(&m_debug,0,sizeof(m_debug));
144
145    char property_value[PROPERTY_VALUE_MAX] = {0};
146    property_value[0] = '\0';
147    property_get("vidc.enc.log.in", property_value, "0");
148    m_debug.in_buffer_log = atoi(property_value);
149
150    property_value[0] = '\0';
151    property_get("vidc.enc.log.out", property_value, "0");
152    m_debug.out_buffer_log = atoi(property_value);
153    snprintf(m_debug.log_loc, PROPERTY_VAL_MAX,
154             "%s", BUFFER_LOG_LOC);
155
156    DEBUG_PRINT_LOW("venc_dev constructor");
157}
158
159venc_dev::~venc_dev()
160{
161    pthread_cond_destroy(&loaded_start_stop_cond);
162    pthread_mutex_destroy(&loaded_start_stop_mlock);
163    DEBUG_PRINT_LOW("venc_dev distructor");
164}
165
166void* async_venc_message_thread (void *input)
167{
168    struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
169    struct venc_timeout timeout;
170    struct venc_msg venc_msg;
171    int error_code = 0;
172    omx_venc *omx = reinterpret_cast<omx_venc*>(input);
173
174    prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
175    timeout.millisec = VEN_TIMEOUT_INFINITE;
176
177    while (1) {
178        ioctl_msg.in = NULL;
179        ioctl_msg.out = (void*)&venc_msg;
180
181        /*Wait for a message from the video decoder driver*/
182        error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg);
183
184        if (error_code == -512) { // ERESTARTSYS
185            DEBUG_PRINT_ERROR("ERESTARTSYS received in ioctl read next msg!");
186        } else if (error_code <0) {
187            DEBUG_PRINT_LOW("ioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
188            break;
189        } else if (omx->async_message_process(input,&venc_msg) < 0) {
190            DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
191            break;
192        }
193    }
194    DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
195    return NULL;
196}
197
198int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
199{
200    return OMX_ErrorUnsupportedSetting;
201}
202
203int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
204{
205    if (m_debug.out_buffer_log && !m_debug.outfile) {
206        int size = 0;
207        if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) {
208           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.m4v",
209                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
210        } else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) {
211           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.264",
212                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
213        } else if(m_sVenc_cfg.codectype == VENC_CODEC_H263) {
214           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.263",
215                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
216        } else if(m_sVenc_cfg.codectype == VENC_CODEC_VP8) {
217           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.ivf",
218                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
219        }
220        if ((size > PROPERTY_VALUE_MAX) || (size < 0)) {
221            DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
222                               m_debug.outfile_name, size);
223            return -1;
224        }
225        m_debug.outfile = fopen(m_debug.outfile_name, "ab");
226        if (!m_debug.outfile) {
227            DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
228                              m_debug.outfile_name, errno);
229            m_debug.outfile_name[0] = '\0';
230            return -1;
231        }
232    }
233    if (m_debug.outfile && buffer_len) {
234        DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
235        fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
236    }
237    return 0;
238}
239
240bool venc_dev::venc_get_output_log_flag()
241{
242    return (m_debug.out_buffer_log == 1);
243}
244
245int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, void *pmem_data_buf, int framelen) {
246    if (!m_debug.infile) {
247        int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%d_%d_%p.yuv",
248                           m_debug.log_loc, m_sVenc_cfg.input_width,
249                           m_sVenc_cfg.input_height, this);
250        if ((size > PROPERTY_VALUE_MAX) || (size < 0)) {
251            DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
252                               m_debug.infile_name, size);
253            return -1;
254        }
255        m_debug.infile = fopen (m_debug.infile_name, "ab");
256        if (!m_debug.infile) {
257            DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile);
258            m_debug.infile_name[0] = '\0';
259            return -1;
260        }
261    }
262    if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
263#ifdef MAX_RES_1080P
264       int y_size = 0;
265       int c_offset = 0;
266       unsigned char *buf_addr = NULL;
267
268       y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
269       //chroma offset is y_size aligned to the 2k boundary
270       c_offset= (y_size + 2047) & (~(2047));
271
272       if (pmem_data_buf) {
273           DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
274           buf_addr = (OMX_U8 *)pmem_data_buf;
275       } else {
276           DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
277           buf_addr = (unsigned char *)mmap(NULL,
278                      ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2],
279                      PROT_READ|PROT_WRITE, MAP_SHARED,
280                      ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[0], 0);
281       }
282
283       if (m_debug.infile) {
284           fwrite((const char *)buf_addr, y_size, 1, m_debug.infile);
285           fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1, m_debug.infile);
286       }
287
288       if (!pmem_data_buf) {
289           munmap (buf_addr, ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2]);
290       }
291#else
292       if (m_debug.infile) {
293           OMX_U8* ptrbuffer = NULL;
294           if (pmem_data_buf) {
295               DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
296               ptrbuffer = (OMX_U8 *)pmem_data_buf;
297           } else {
298               DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
299               ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
300           }
301           fwrite((const char *)ptrbuffer, framelen, 1, m_debug.infile);
302       }
303
304#endif
305    }
306    return 0;
307}
308
309bool venc_dev::venc_open(OMX_U32 codec)
310{
311    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
312    int r;
313    unsigned int   alignment = 0,buffer_size = 0, temp =0;
314
315    m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
316
317    if (m_nDriver_fd == 0) {
318        DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
319        m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
320    }
321
322    if ((int)m_nDriver_fd < 0) {
323        DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
324        return false;
325    }
326
327    DEBUG_PRINT_LOW("m_nDriver_fd = %d", m_nDriver_fd);
328#ifdef SINGLE_ENCODER_INSTANCE
329    OMX_U32 num_instances = 0;
330    ioctl_msg.in = NULL;
331    ioctl_msg.out = &num_instances;
332
333    if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 ) {
334        DEBUG_PRINT_ERROR("ERROR: Request number of encoder instances failed");
335    } else if (num_instances > 1) {
336        DEBUG_PRINT_ERROR("Second encoder instance rejected!");
337        venc_close();
338        return false;
339    }
340
341#endif
342    // set the basic configuration of the video encoder driver
343    m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
344    m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
345    m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
346    m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
347    m_sVenc_cfg.fps_num = 30;
348    m_sVenc_cfg.fps_den = 1;
349    m_sVenc_cfg.targetbitrate = 64000;
350#ifdef MAX_RES_1080P
351    m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
352#else
353    m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12;
354#endif
355    // initializing QP range parameters
356    qp_range.minqp = 2;
357
358    if (codec == OMX_VIDEO_CodingAVC)
359        qp_range.maxqp = 51;
360    else
361        qp_range.maxqp = 31;
362
363    if (codec == OMX_VIDEO_CodingMPEG4) {
364        m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
365        codec_profile.profile = VEN_PROFILE_MPEG4_SP;
366        profile_level.level = VEN_LEVEL_MPEG4_2;
367    } else if (codec == OMX_VIDEO_CodingH263) {
368        m_sVenc_cfg.codectype = VEN_CODEC_H263;
369        codec_profile.profile = VEN_PROFILE_H263_BASELINE;
370        profile_level.level = VEN_LEVEL_H263_20;
371    }
372
373    if (codec == OMX_VIDEO_CodingAVC) {
374        m_sVenc_cfg.codectype = VEN_CODEC_H264;
375        codec_profile.profile = VEN_PROFILE_H264_BASELINE;
376        profile_level.level = VEN_LEVEL_H264_1p1;
377    }
378
379    ioctl_msg.in = (void*)&m_sVenc_cfg;
380    ioctl_msg.out = NULL;
381
382    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 ) {
383        DEBUG_PRINT_ERROR("ERROR: Request for setting base configuration failed");
384        return false;
385    }
386
387    // Get the I/P and O/P buffer requirements
388    ioctl_msg.in = NULL;
389    ioctl_msg.out = (void*)&m_sInput_buff_property;
390
391    if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
392        DEBUG_PRINT_ERROR("ERROR: Request for getting i/p buffer requirement failed");
393        return false;
394    }
395
396    ioctl_msg.in = NULL;
397    ioctl_msg.out = (void*)&m_sOutput_buff_property;
398
399    if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
400        DEBUG_PRINT_ERROR("ERROR: Request for getting o/p buffer requirement failed");
401        return false;
402    }
403
404    m_profile_set = false;
405    m_level_set = false;
406
407    if (venc_set_profile_level(0, 0)) {
408        DEBUG_PRINT_HIGH("%s(): Init Profile/Level setting success",
409                __func__);
410    }
411
412    recon_buffers_count = MAX_RECON_BUFFERS;
413    ltrmode.ltr_mode = 0;
414    ltrcount.ltr_count = 0;
415    ltrperiod.ltr_period = 0;
416
417    return true;
418}
419
420void venc_dev::venc_close()
421{
422    DEBUG_PRINT_LOW("venc_close: fd = %d", m_nDriver_fd);
423
424    if ((int)m_nDriver_fd >= 0) {
425        DEBUG_PRINT_HIGH("venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
426        (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
427                NULL);
428        DEBUG_PRINT_LOW("Calling close()");
429        close(m_nDriver_fd);
430        m_nDriver_fd = -1;
431    }
432
433    if (m_debug.infile) {
434        fclose(m_debug.infile);
435        m_debug.infile = NULL;
436    }
437    if (m_debug.outfile) {
438        fclose(m_debug.outfile);
439        m_debug.outfile = NULL;
440    }
441
442}
443
444bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
445        unsigned long *actual_buff_count,
446        unsigned long *buff_size,
447        unsigned long port)
448{
449    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
450    unsigned long temp_count = 0;
451
452    if (port == 0) {
453        if (*actual_buff_count > m_sInput_buff_property.mincount) {
454            temp_count = m_sInput_buff_property.actualcount;
455            m_sInput_buff_property.actualcount = *actual_buff_count;
456            ioctl_msg.in = (void*)&m_sInput_buff_property;
457            ioctl_msg.out = NULL;
458
459            if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
460                DEBUG_PRINT_ERROR("ERROR: Request for setting i/p buffer requirement failed");
461                m_sInput_buff_property.actualcount = temp_count;
462                return false;
463            }
464
465            DEBUG_PRINT_LOW("I/P Count set to %lu", *actual_buff_count);
466        }
467    } else {
468        if (*actual_buff_count > m_sOutput_buff_property.mincount) {
469            temp_count = m_sOutput_buff_property.actualcount;
470            m_sOutput_buff_property.actualcount = *actual_buff_count;
471            ioctl_msg.in = (void*)&m_sOutput_buff_property;
472            ioctl_msg.out = NULL;
473
474            if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
475                DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer requirement failed");
476                m_sOutput_buff_property.actualcount = temp_count;
477                return false;
478            }
479
480            DEBUG_PRINT_LOW("O/P Count set to %lu", *actual_buff_count);
481        }
482    }
483
484    return true;
485
486}
487
488bool venc_dev::venc_loaded_start()
489{
490    struct timespec ts;
491    int status = 0;
492
493    if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0) {
494        DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed");
495        return false;
496    }
497
498    if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
499        DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
500        return false;
501    }
502
503    ts.tv_sec += 1;
504    pthread_mutex_lock(&loaded_start_stop_mlock);
505    DEBUG_PRINT_LOW("%s: wait on start done", __func__);
506    status = pthread_cond_timedwait(&loaded_start_stop_cond,
507            &loaded_start_stop_mlock, &ts);
508
509    if (status != 0) {
510        DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
511                status, strerror(status));
512        pthread_mutex_unlock(&loaded_start_stop_mlock);
513        return false;
514    }
515
516    DEBUG_PRINT_LOW("%s: wait over on start done", __func__);
517    pthread_mutex_unlock(&loaded_start_stop_mlock);
518    DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__);
519    return true;
520}
521
522bool venc_dev::venc_loaded_stop()
523{
524    struct timespec ts;
525    int status = 0;
526
527    if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0) {
528        DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed");
529        return false;
530    }
531
532    if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
533        DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
534        return false;
535    }
536
537    ts.tv_sec += 1;
538    pthread_mutex_lock(&loaded_start_stop_mlock);
539    DEBUG_PRINT_LOW("%s: wait on stop done", __func__);
540    status = pthread_cond_timedwait(&loaded_start_stop_cond,
541            &loaded_start_stop_mlock, &ts);
542
543    if (status != 0) {
544        DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
545                status, strerror(status));
546        pthread_mutex_unlock(&loaded_start_stop_mlock);
547        return false;
548    }
549
550    DEBUG_PRINT_LOW("%s: wait over on stop done", __func__);
551    pthread_mutex_unlock(&loaded_start_stop_mlock);
552    DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__);
553    return true;
554}
555
556bool venc_dev::venc_loaded_start_done()
557{
558    pthread_mutex_lock(&loaded_start_stop_mlock);
559    DEBUG_PRINT_LOW("%s: signal start done", __func__);
560    pthread_cond_signal(&loaded_start_stop_cond);
561    pthread_mutex_unlock(&loaded_start_stop_mlock);
562    return true;
563}
564
565bool venc_dev::venc_loaded_stop_done()
566{
567    pthread_mutex_lock(&loaded_start_stop_mlock);
568    DEBUG_PRINT_LOW("%s: signal stop done", __func__);
569    pthread_cond_signal(&loaded_start_stop_cond);
570    pthread_mutex_unlock(&loaded_start_stop_mlock);
571    return true;
572}
573
574bool venc_dev::venc_get_seq_hdr(void *buffer,
575        unsigned buffer_size, unsigned *header_len)
576{
577    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
578    int i = 0;
579    DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr");
580    venc_seqheader seq_in, seq_out;
581    seq_in.hdrlen = 0;
582    seq_in.bufsize = buffer_size;
583    seq_in.hdrbufptr = (unsigned char*)buffer;
584
585    if (seq_in.hdrbufptr == NULL) {
586        DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed");
587        return false;
588    }
589
590    DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr,
591            seq_in.bufsize, seq_in.hdrlen);
592
593    ioctl_msg.in = (void*)&seq_in;
594    ioctl_msg.out = (void*)&seq_out;
595
596    if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0) {
597        DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed");
598        return false;
599    }
600
601    if (seq_out.hdrlen == 0) {
602        DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header");
603        DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
604                seq_out.bufsize, seq_out.hdrlen);
605        return false;
606    }
607
608    *header_len = seq_out.hdrlen;
609    DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
610            seq_out.bufsize, seq_out.hdrlen);
611
612    return true;
613}
614
615bool venc_dev::venc_get_capability_ltrcount(unsigned long *min,
616        unsigned long *max, unsigned long *step_size)
617{
618    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
619    venc_range  cap_ltr_count;
620    ioctl_msg.in = NULL;
621    ioctl_msg.out = (void*)&cap_ltr_count;
622
623    if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT,
624                (void*)&ioctl_msg) < 0) {
625        DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed");
626        return false;
627    } else {
628        *min = cap_ltr_count.min;
629        *max = cap_ltr_count.max;
630        *step_size = cap_ltr_count.step_size;
631        DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d",
632                *min, *max, *step_size);
633    }
634
635    return true;
636}
637
638bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
639        unsigned long *actual_buff_count,
640        unsigned long *buff_size,
641        unsigned long port)
642{
643    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
644
645    if (port == 0) {
646        ioctl_msg.in = NULL;
647        ioctl_msg.out = (void*)&m_sInput_buff_property;
648
649        if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
650            DEBUG_PRINT_ERROR("ERROR: Request for getting i/p buffer requirement failed");
651            return false;
652        }
653
654        *min_buff_count = m_sInput_buff_property.mincount;
655        *actual_buff_count = m_sInput_buff_property.actualcount;
656#ifdef USE_ION
657        // For ION memory allocations of the allocated buffer size
658        // must be 4k aligned, hence aligning the input buffer
659        // size to 4k.
660        m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
661            & (~4095);
662#endif
663        *buff_size = m_sInput_buff_property.datasize;
664    } else {
665        ioctl_msg.in = NULL;
666        ioctl_msg.out = (void*)&m_sOutput_buff_property;
667
668        if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
669            DEBUG_PRINT_ERROR("ERROR: Request for getting o/p buffer requirement failed");
670            return false;
671        }
672
673        *min_buff_count = m_sOutput_buff_property.mincount;
674        *actual_buff_count = m_sOutput_buff_property.actualcount;
675        *buff_size = m_sOutput_buff_property.datasize;
676    }
677
678    return true;
679
680}
681
682bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
683{
684    venc_ioctl_msg ioctl_msg = {NULL,NULL};
685    DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
686
687    switch (index) {
688        case OMX_IndexParamPortDefinition:
689            {
690                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
691                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
692                DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition");
693
694                if (portDefn->nPortIndex == PORT_INDEX_IN) {
695
696                    if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
697                        return false;
698                    }
699
700                    if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
701                        return false;
702                    }
703
704                    DEBUG_PRINT_LOW("Basic parameter has changed");
705                    m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
706                    m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
707
708                    ioctl_msg.in = (void*)&m_sVenc_cfg;
709                    ioctl_msg.out = NULL;
710
711                    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
712                        DEBUG_PRINT_ERROR("ERROR: Request for setting base config failed");
713                        return false;
714                    }
715
716                    DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), "
717                            "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
718                            m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den,
719                            m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat);
720
721                    DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution");
722                    ioctl_msg.in = NULL;
723                    ioctl_msg.out = (void*)&m_sInput_buff_property;
724
725                    if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
726                        DEBUG_PRINT_ERROR("ERROR: Request for getting i/p bufreq failed");
727                        return false;
728                    }
729
730                    DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: "
731                            "datasize = %u, maxcount = %u, actualcnt = %u, "
732                            "mincount = %u", m_sInput_buff_property.datasize,
733                            m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
734                            m_sInput_buff_property.mincount);
735
736                    ioctl_msg.in = NULL;
737                    ioctl_msg.out = (void*)&m_sOutput_buff_property;
738
739                    if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
740                        DEBUG_PRINT_ERROR("ERROR: Request for getting o/p bufreq failed");
741                        return false;
742                    }
743
744                    DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: "
745                            "datasize = %u, maxcount = %u, actualcnt = %u, "
746                            "mincount = %u", m_sOutput_buff_property.datasize,
747                            m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
748                            m_sOutput_buff_property.mincount);
749                    ioctl_msg.in = (void*)&m_sOutput_buff_property;
750                    ioctl_msg.out = NULL;
751
752                    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
753                        DEBUG_PRINT_ERROR("ERROR: Request for setting o/p bufreq failed");
754                        return false;
755                    }
756
757                    if ((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
758                            (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) {
759                        m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
760                        ioctl_msg.in = (void*)&m_sInput_buff_property;
761                        ioctl_msg.out = NULL;
762
763                        if (ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
764                            DEBUG_PRINT_ERROR("ERROR: Request for setting i/p buffer requirements failed");
765                            return false;
766                        }
767                    }
768
769                    if (m_sInput_buff_property.datasize != portDefn->nBufferSize) {
770                        DEBUG_PRINT_ERROR("WARNING: Requested i/p bufsize[%u],"
771                                "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
772                                m_sInput_buff_property.datasize);
773                    }
774
775                    m_level_set = false;
776
777                    if (venc_set_profile_level(0, 0)) {
778                        DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__);
779                    }
780                } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
781                    if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
782                        return false;
783                    }
784
785                    if ( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
786                            &&
787                            (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
788                            &&
789                            (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
790                       ) {
791                        m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
792                        ioctl_msg.in = (void*)&m_sOutput_buff_property;
793                        ioctl_msg.out = NULL;
794
795                        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
796                            DEBUG_PRINT_ERROR("ERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
797                            return false;
798                        }
799                    } else {
800                        DEBUG_PRINT_ERROR("ERROR: Setting Output buffer requirements failed");
801                        return false;
802                    }
803                } else {
804                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
805                }
806
807                break;
808            }
809        case OMX_IndexParamVideoPortFormat:
810            {
811                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
812                portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
813                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
814
815                if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
816                    if (!venc_set_color_format(portFmt->eColorFormat)) {
817                        return false;
818                    }
819                } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
820                    if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
821                        return false;
822                    }
823                } else {
824                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
825                }
826
827                break;
828            }
829        case OMX_IndexParamVideoBitrate:
830            {
831                OMX_VIDEO_PARAM_BITRATETYPE* pParam;
832                pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
833                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
834
835                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
836                    if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
837                        DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
838                        return false;
839                    }
840
841                    if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
842                        DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
843                        return false;
844                    }
845                } else {
846                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
847                }
848
849                break;
850            }
851        case OMX_IndexParamVideoMpeg4:
852            {
853                OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
854                OMX_U32 bFrames = 0;
855
856                pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
857                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
858
859                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
860                    if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
861                        DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
862                        return false;
863                    }
864
865                    m_profile_set = false;
866                    m_level_set = false;
867
868                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
869                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
870                        return false;
871                    }
872
873#ifdef MAX_RES_1080P
874                    else {
875                        if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
876                            if (pParam->nBFrames) {
877                                DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
878                                bFrames = 1;
879                            }
880                        } else {
881                            if (pParam->nBFrames) {
882                                DEBUG_PRINT_ERROR("Warning: B frames not supported");
883                                bFrames = 0;
884                            }
885                        }
886                    }
887
888#endif
889
890                    if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
891                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
892                        return false;
893                    }
894
895                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
896                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
897                        return false;
898                    }
899                } else {
900                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
901                }
902
903                break;
904            }
905        case OMX_IndexParamVideoH263:
906            {
907                OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
908                DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
909                OMX_U32 bFrames = 0;
910
911                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
912                    m_profile_set = false;
913                    m_level_set = false;
914
915                    if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
916                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
917                        return false;
918                    }
919
920                    if (pParam->nBFrames)
921                        DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
922
923                    if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
924                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
925                        return false;
926                    }
927                } else {
928                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
929                }
930
931                break;
932            }
933        case OMX_IndexParamVideoAvc:
934            {
935                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
936                OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
937                OMX_U32 bFrames = 0;
938
939                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
940                    DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
941                            pParam->eProfile,pParam->eLevel);
942
943                    m_profile_set = false;
944                    m_level_set = false;
945
946                    if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
947                        DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
948                                pParam->eProfile, pParam->eLevel);
949                        return false;
950                    }
951
952#ifdef MAX_RES_1080P
953                    else {
954                        if (pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) {
955                            if (pParam->nBFrames) {
956                                DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
957                                bFrames = 1;
958                            }
959                        } else {
960                            if (pParam->nBFrames) {
961                                DEBUG_PRINT_ERROR("Warning: B frames not supported");
962                                bFrames = 0;
963                            }
964                        }
965                    }
966
967#endif
968
969                    if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
970                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
971                        return false;
972                    }
973
974                    if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
975                        DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
976                        return false;
977                    }
978
979                    if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
980                        DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
981                        return false;
982                    }
983
984                    if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
985                        DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
986                        return false;
987                    }
988                } else {
989                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
990                }
991
992                //TBD, lot of other variables to be updated, yet to decide
993                break;
994            }
995        case OMX_IndexParamVideoIntraRefresh:
996            {
997                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
998                OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
999                    (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1000
1001                if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1002                    if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1003                        DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1004                        return false;
1005                    }
1006                } else {
1007                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1008                }
1009
1010                break;
1011            }
1012        case OMX_IndexParamVideoErrorCorrection:
1013            {
1014                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1015                OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1016                    (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1017
1018                if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1019                    if (venc_set_error_resilience(error_resilience) == false) {
1020                        DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1021                        return false;
1022                    }
1023                } else {
1024                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1025                }
1026
1027                break;
1028            }
1029        case OMX_IndexParamVideoProfileLevelCurrent:
1030            {
1031                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1032                OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1033                    (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1034
1035                if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1036                    m_profile_set = false;
1037                    m_level_set = false;
1038
1039                    if (!venc_set_profile_level (profile_level->eProfile,
1040                                profile_level->eLevel)) {
1041                        DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1042                        return false;
1043                    }
1044                } else {
1045                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1046                }
1047
1048                break;
1049            }
1050        case OMX_IndexParamVideoQuantization:
1051            {
1052                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
1053                OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1054                    (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1055
1056                if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1057                    if (venc_set_session_qp (session_qp->nQpI,
1058                                session_qp->nQpP) == false) {
1059                        DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
1060                        return false;
1061                    }
1062                } else {
1063                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1064                }
1065
1066                break;
1067            }
1068
1069        case OMX_QcomIndexParamVideoQPRange:
1070            {
1071                DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
1072                OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range =
1073                    (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
1074
1075                if (qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1076                    if (venc_set_qp_range (qp_range->minQP,
1077                                qp_range->maxQP) == false) {
1078                        DEBUG_PRINT_ERROR("ERROR: Setting QP Range failed");
1079                        return false;
1080                    }
1081                } else {
1082                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1083                }
1084
1085                break;
1086            }
1087
1088        case OMX_ExtraDataVideoEncoderSliceInfo:
1089            {
1090                DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1091                OMX_U32 extra_data = *(OMX_U32 *)paramData;
1092
1093                if (venc_set_extradata(extra_data) == false) {
1094                    DEBUG_PRINT_ERROR("ERROR: Setting "
1095                            "OMX_ExtraDataVideoEncoderSliceInfo failed");
1096                    return false;
1097                }
1098
1099                break;
1100            }
1101        case OMX_ExtraDataVideoLTRInfo:
1102            {
1103                DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo");
1104                OMX_U32 extra_data = *(OMX_U32 *)paramData;
1105
1106                if (venc_set_extradata(extra_data) == false) {
1107                    DEBUG_PRINT_ERROR("ERROR: Setting "
1108                            "OMX_ExtraDataVideoLTRInfo failed");
1109                    return false;
1110                }
1111
1112                break;
1113            }
1114        case OMX_QcomIndexEnableSliceDeliveryMode:
1115            {
1116                QOMX_EXTNINDEX_PARAMTYPE* pParam =
1117                    (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1118
1119                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1120                    if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1121                        DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1122                        return OMX_ErrorUnsupportedSetting;
1123                    }
1124                } else {
1125                    DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1126                            "called on wrong port(%d)", pParam->nPortIndex);
1127                    return OMX_ErrorBadPortIndex;
1128                }
1129
1130                break;
1131            }
1132        case OMX_QcomIndexEnableH263PlusPType:
1133            {
1134                QOMX_EXTNINDEX_PARAMTYPE* pParam =
1135                    (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1136                DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
1137
1138                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1139                    if (venc_set_plusptype(pParam->bEnable) == false) {
1140                        DEBUG_PRINT_ERROR("Setting PlusPType failed for H263");
1141                        return OMX_ErrorUnsupportedSetting;
1142                    }
1143                } else {
1144                    DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType "
1145                            "called on wrong port(%d)", pParam->nPortIndex);
1146                    return OMX_ErrorBadPortIndex;
1147                }
1148
1149                break;
1150            }
1151        case QOMX_IndexParamVideoLTRMode:
1152            {
1153                QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam =
1154                    (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData;
1155
1156                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1157                    if (!venc_set_ltrmode(pParam->eLTRMode)) {
1158                        DEBUG_PRINT_ERROR("Setting ltr mode failed");
1159                        return OMX_ErrorUnsupportedSetting;
1160                    }
1161                } else {
1162                    DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode "
1163                            "called on wrong port(%d)", pParam->nPortIndex);
1164                    return OMX_ErrorBadPortIndex;
1165                }
1166
1167                break;
1168            }
1169        case QOMX_IndexParamVideoLTRCount:
1170            {
1171                QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1172                    (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1173
1174                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1175                    if (!venc_set_ltrcount(pParam->nCount)) {
1176                        DEBUG_PRINT_ERROR("Setting ltr count failed");
1177                        return OMX_ErrorUnsupportedSetting;
1178                    }
1179                } else {
1180                    DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount "
1181                            "called on wrong port(%d)", pParam->nPortIndex);
1182                    return OMX_ErrorBadPortIndex;
1183                }
1184
1185                break;
1186            }
1187        case OMX_IndexParamVideoSliceFMO:
1188        default:
1189            DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index);
1190            break;
1191    }
1192
1193    return true;
1194}
1195
1196bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1197{
1198    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1199    DEBUG_PRINT_LOW("Inside venc_set_config");
1200
1201    switch (index) {
1202        case OMX_IndexConfigVideoBitrate:
1203            {
1204                OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1205                    configData;
1206
1207                if (m_max_allowed_bitrate_check &&
1208                        !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate)) {
1209                    DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed");
1210                    return false;
1211                }
1212
1213                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
1214
1215                if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1216                    if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1217                        DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
1218                        return false;
1219                    }
1220                } else {
1221                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1222                }
1223
1224                break;
1225            }
1226        case OMX_IndexConfigVideoFramerate:
1227            {
1228                OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1229                    configData;
1230                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
1231
1232                if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1233                    if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1234                        DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1235                        return false;
1236                    }
1237                } else {
1238                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1239                }
1240
1241                break;
1242            }
1243        case QOMX_IndexConfigVideoIntraperiod:
1244            {
1245                DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
1246                QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1247                    (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1248
1249                if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1250                    if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1251                        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1252                        return false;
1253                    }
1254                }
1255
1256                break;
1257            }
1258        case OMX_IndexConfigVideoIntraVOPRefresh:
1259            {
1260                OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1261                    configData;
1262                DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1263
1264                if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1265                    if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
1266                        DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1267                        return false;
1268                    }
1269                } else {
1270                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1271                }
1272
1273                break;
1274            }
1275        case OMX_IndexConfigCommonRotate:
1276            {
1277                OMX_CONFIG_ROTATIONTYPE *config_rotation =
1278                    reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1279                venc_ioctl_msg ioctl_msg = {NULL,NULL};
1280                OMX_U32 nFrameWidth;
1281
1282                DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
1283                nFrameWidth = m_sVenc_cfg.input_width;
1284                m_sVenc_cfg.input_width  = m_sVenc_cfg.input_height;
1285                m_sVenc_cfg.input_height = nFrameWidth;
1286                ioctl_msg.in = (void*)&m_sVenc_cfg;
1287                ioctl_msg.out = NULL;
1288
1289                if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
1290                    DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
1291                    return false;
1292                }
1293
1294                break;
1295            }
1296        case QOMX_IndexConfigVideoLTRPeriod:
1297            {
1298                QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam =
1299                    (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData;
1300
1301                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1302                    if (!venc_set_ltrperiod(pParam->nFrames)) {
1303                        DEBUG_PRINT_ERROR("Setting ltr period failed");
1304                        return OMX_ErrorUnsupportedSetting;
1305                    }
1306                } else {
1307                    DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod "
1308                            "called on wrong port(%d)", pParam->nPortIndex);
1309                    return OMX_ErrorBadPortIndex;
1310                }
1311
1312                break;
1313            }
1314        case QOMX_IndexConfigVideoLTRUse:
1315            {
1316                QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam =
1317                    (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
1318
1319                if (pParam->nPortIndex == PORT_INDEX_OUT) {
1320                    if (!venc_set_ltruse(pParam->nID, pParam->nFrames)) {
1321                        DEBUG_PRINT_ERROR("Setting ltr use failed");
1322                        return OMX_ErrorUnsupportedSetting;
1323                    }
1324                } else {
1325                    DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse "
1326                            "called on wrong port(%d)", pParam->nPortIndex);
1327                    return OMX_ErrorBadPortIndex;
1328                }
1329
1330                break;
1331            }
1332        default:
1333            DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index);
1334            break;
1335    }
1336
1337    return true;
1338}
1339
1340unsigned venc_dev::venc_stop( void)
1341{
1342#ifdef MAX_RES_1080P
1343    pmem_free();
1344#endif
1345    return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
1346}
1347
1348unsigned venc_dev::venc_pause(void)
1349{
1350    return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
1351}
1352
1353unsigned venc_dev::venc_resume(void)
1354{
1355    return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
1356}
1357
1358unsigned venc_dev::venc_start_done(void)
1359{
1360    return 0;
1361}
1362
1363unsigned venc_dev::venc_set_message_thread_id(pthread_t)
1364{
1365    return 0;
1366}
1367
1368unsigned venc_dev::venc_start(void)
1369{
1370    DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
1371            __func__);
1372
1373    if (!venc_set_profile_level(0, 0)) {
1374        DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
1375                __func__);
1376    } else {
1377        DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
1378                __func__, codec_profile.profile, profile_level.level);
1379    }
1380
1381    if (m_max_allowed_bitrate_check &&
1382            !venc_max_allowed_bitrate_check(bitrate.target_bitrate)) {
1383        DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed");
1384        return -1;
1385    }
1386
1387    venc_config_print();
1388
1389#ifdef MAX_RES_1080P
1390
1391    if ((codec_profile.profile == VEN_PROFILE_MPEG4_SP) ||
1392            (codec_profile.profile == VEN_PROFILE_H264_BASELINE) ||
1393            (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
1394        recon_buffers_count = MAX_RECON_BUFFERS - 2;
1395    else
1396        recon_buffers_count = MAX_RECON_BUFFERS;
1397
1398    if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto) {
1399        recon_buffers_count = MAX_RECON_BUFFERS;
1400        DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers "
1401                "count to %d", recon_buffers_count);
1402    }
1403
1404    if (!venc_allocate_recon_buffers())
1405        return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
1406    else {
1407        DEBUG_PRINT_ERROR("Failed in creating Recon buffers");
1408        return -1;
1409    }
1410
1411#else
1412    return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
1413#endif
1414}
1415
1416#ifdef MAX_RES_1080P
1417OMX_U32 venc_dev::venc_allocate_recon_buffers()
1418{
1419    OMX_U32 yuv_size;
1420    struct venc_ioctl_msg ioctl_msg;
1421    struct venc_recon_buff_size recon_buff_size;
1422
1423    recon_buff_size.width =  ((m_sVenc_cfg.input_width + 15) / 16) * 16;
1424    recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16;
1425
1426    DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d", m_sVenc_cfg.input_width,
1427            m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height);
1428
1429    ioctl_msg.in = NULL;
1430    ioctl_msg.out = (void*)&recon_buff_size;
1431
1432    if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0) {
1433        DEBUG_PRINT_ERROR("VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" ,
1434                recon_buff_size.width, recon_buff_size.height);
1435        return OMX_ErrorInsufficientResources;
1436    }
1437
1438    DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d",
1439            m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width,
1440            recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment,
1441            recon_buffers_count);
1442
1443    for (int i = 0; i < recon_buffers_count; i++) {
1444        if (pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i)) {
1445            DEBUG_PRINT_ERROR("Error returned in allocating recon buffers");
1446            return -1;
1447        }
1448    }
1449
1450    return 0;
1451}
1452OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
1453{
1454    OMX_U32 pmem_fd = -1;
1455    OMX_U32 width, height;
1456    void *buf_addr = NULL;
1457    struct venc_ioctl_msg ioctl_msg;
1458    struct venc_recon_addr recon_addr;
1459    int rc = 0;
1460
1461#ifdef USE_ION
1462    recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY);
1463
1464    if (recon_buff[count].ion_device_fd < 0) {
1465        DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
1466        return -1;
1467    }
1468
1469    recon_buff[count].alloc_data.len = size;
1470#ifdef MAX_RES_720P
1471    recon_buff[count].alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
1472#else
1473    recon_buff[count].alloc_data.heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
1474            ION_HEAP(ION_IOMMU_HEAP_ID));
1475#endif
1476    recon_buff[count].alloc_data.flags = ION_FLAG_CACHED;
1477    recon_buff[count].alloc_data.align = clip2(alignment);
1478
1479    if (recon_buff[count].alloc_data.align != 8192)
1480        recon_buff[count].alloc_data.align = 8192;
1481
1482    rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
1483
1484    if (rc || !recon_buff[count].alloc_data.handle) {
1485        DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
1486        recon_buff[count].alloc_data.handle=NULL;
1487        return -1;
1488    }
1489
1490    recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
1491    rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
1492
1493    if (rc) {
1494        DEBUG_PRINT_ERROR("ION MAP failed ");
1495        recon_buff[count].ion_alloc_fd.fd =-1;
1496        recon_buff[count].ion_alloc_fd.fd =-1;
1497        return -1;
1498    }
1499
1500    pmem_fd = recon_buff[count].ion_alloc_fd.fd;
1501#else
1502    struct pmem_allocation allocation;
1503    pmem_fd = open(MEM_DEVICE, O_RDWR);
1504
1505    if ((int)(pmem_fd) < 0) {
1506        DEBUG_PRINT_ERROR("Failed to get an pmem handle");
1507        return -1;
1508    }
1509
1510    allocation.size = size;
1511    allocation.align = clip2(alignment);
1512
1513    if (allocation.align != 8192)
1514        allocation.align = 8192;
1515
1516    if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
1517        DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
1518                allocation.align, allocation.size);
1519        return -1;
1520    }
1521
1522#endif
1523    buf_addr = mmap(NULL, size,
1524            PROT_READ | PROT_WRITE,
1525            MAP_SHARED, pmem_fd, 0);
1526
1527    if (buf_addr == (void*) MAP_FAILED) {
1528        close(pmem_fd);
1529        pmem_fd = -1;
1530        DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p",buf_addr);
1531#ifdef USE_ION
1532
1533        if (ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
1534                    &recon_buff[count].alloc_data.handle)) {
1535            DEBUG_PRINT_LOW("ion recon buffer free failed");
1536        }
1537
1538        recon_buff[count].alloc_data.handle = NULL;
1539        recon_buff[count].ion_alloc_fd.fd =-1;
1540        close(recon_buff[count].ion_device_fd);
1541        recon_buff[count].ion_device_fd =-1;
1542#endif
1543        return -1;
1544    }
1545
1546    DEBUG_PRINT_HIGH("Allocated virt:%p, FD: %d of size %d", buf_addr, pmem_fd, size);
1547
1548    recon_addr.buffer_size = size;
1549    recon_addr.pmem_fd = pmem_fd;
1550    recon_addr.offset = 0;
1551    recon_addr.pbuffer = (unsigned char *)buf_addr;
1552
1553    ioctl_msg.in = (void*)&recon_addr;
1554    ioctl_msg.out = NULL;
1555
1556    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0) {
1557        DEBUG_PRINT_ERROR("Failed to set the Recon_buffers");
1558        return -1;
1559    }
1560
1561    recon_buff[count].virtual_address = (unsigned char *) buf_addr;
1562    recon_buff[count].size = size;
1563    recon_buff[count].offset = 0;
1564    recon_buff[count].pmem_fd = pmem_fd;
1565
1566    DEBUG_PRINT_ERROR("Allocated virt:%p, FD: %d of size %d at index: %d", recon_buff[count].virtual_address,
1567            recon_buff[count].pmem_fd, recon_buff[count].size, count);
1568    return 0;
1569}
1570
1571OMX_U32 venc_dev::pmem_free()
1572{
1573    int cnt = 0;
1574    struct venc_ioctl_msg ioctl_msg;
1575    struct venc_recon_addr recon_addr;
1576
1577    for (cnt = 0; cnt < recon_buffers_count; cnt++) {
1578        if (recon_buff[cnt].pmem_fd) {
1579            recon_addr.pbuffer = recon_buff[cnt].virtual_address;
1580            recon_addr.offset = recon_buff[cnt].offset;
1581            recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
1582            recon_addr.buffer_size = recon_buff[cnt].size;
1583            ioctl_msg.in = (void*)&recon_addr;
1584            ioctl_msg.out = NULL;
1585
1586            if (ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0)
1587                DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
1588
1589            munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
1590            close(recon_buff[cnt].pmem_fd);
1591#ifdef USE_ION
1592
1593            if (ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
1594                        &recon_buff[cnt].alloc_data.handle)) {
1595                DEBUG_PRINT_LOW("ion recon buffer free failed");
1596            }
1597
1598            recon_buff[cnt].alloc_data.handle = NULL;
1599            recon_buff[cnt].ion_alloc_fd.fd =-1;
1600            close(recon_buff[cnt].ion_device_fd);
1601            recon_buff[cnt].ion_device_fd =-1;
1602#endif
1603            DEBUG_PRINT_LOW("cleaning Index %d of size %d",cnt,recon_buff[cnt].size);
1604            recon_buff[cnt].pmem_fd = -1;
1605            recon_buff[cnt].virtual_address = NULL;
1606            recon_buff[cnt].offset = 0;
1607            recon_buff[cnt].alignment = 0;
1608            recon_buff[cnt].size = 0;
1609        }
1610    }
1611
1612    return 0;
1613}
1614#endif
1615
1616void venc_dev::venc_config_print()
1617{
1618
1619    DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %d, Profile %d, level : %d",
1620            m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
1621
1622    DEBUG_PRINT_HIGH("ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
1623            m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
1624            m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
1625
1626    DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
1627            bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
1628
1629    DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
1630            session_qp.iframeqp, session_qp.pframqp);
1631
1632    DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %d, maxQP: %d",
1633            qp_range.minqp, qp_range.maxqp);
1634
1635    DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
1636            voptimecfg.voptime_resolution, multislice.mslice_mode,
1637            multislice.mslice_size);
1638
1639    DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %d",
1640            entropy.longentropysel, entropy.cabacmodel);
1641
1642    DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d",
1643            dbkfilter.db_mode, dbkfilter.slicealpha_offset,
1644            dbkfilter.slicebeta_offset);
1645
1646    DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %d, HEC: %d",
1647            intra_refresh.mbcount, hec.header_extension);
1648}
1649
1650unsigned venc_dev::venc_flush( unsigned port)
1651{
1652    struct venc_ioctl_msg ioctl_msg;
1653    struct venc_bufferflush buffer_index;
1654
1655    if (port == PORT_INDEX_IN) {
1656        DEBUG_PRINT_HIGH("Calling Input Flush");
1657        buffer_index.flush_mode = VEN_FLUSH_INPUT;
1658        ioctl_msg.in = (void*)&buffer_index;
1659        ioctl_msg.out = NULL;
1660
1661        return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
1662    } else if (port == PORT_INDEX_OUT) {
1663        DEBUG_PRINT_HIGH("Calling Output Flush");
1664        buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
1665        ioctl_msg.in = (void*)&buffer_index;
1666        ioctl_msg.out = NULL;
1667        return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
1668    } else {
1669        return -1;
1670    }
1671}
1672
1673//allocating I/P memory from pmem and register with the device
1674
1675
1676bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned)
1677{
1678    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1679    struct pmem *pmem_tmp;
1680    struct venc_bufferpayload dev_buffer = {0};
1681    struct venc_allocatorproperty buff_alloc_property = {0};
1682
1683    pmem_tmp = (struct pmem *)buf_addr;
1684
1685    DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
1686
1687    if (port == PORT_INDEX_IN) {
1688        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1689        dev_buffer.fd  = pmem_tmp->fd;
1690        dev_buffer.maped_size = pmem_tmp->size;
1691        dev_buffer.sz = pmem_tmp->size;
1692        dev_buffer.offset = pmem_tmp->offset;
1693
1694        if ((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0)) {
1695            unsigned long ht = m_sVenc_cfg.input_height;
1696            unsigned long wd = m_sVenc_cfg.input_width;
1697            unsigned int luma_size, luma_size_2k;
1698
1699            ht = (ht + 15) & ~15;
1700            wd = (wd + 15) & ~15;
1701
1702            luma_size = ht * wd;
1703            luma_size_2k = (luma_size + 2047) & ~2047;
1704
1705            dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047);
1706#ifdef USE_ION
1707            ioctl_msg.in = NULL;
1708            ioctl_msg.out = (void*)&buff_alloc_property;
1709
1710            if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
1711                DEBUG_PRINT_ERROR("ERROR: venc_use_buf:get input buffer failed ");
1712                return false;
1713            }
1714
1715            if (buff_alloc_property.alignment < 4096) {
1716                dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095);
1717            } else {
1718                dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) &
1719                        ~(buff_alloc_property.alignment - 1));
1720            }
1721
1722#endif
1723            dev_buffer.maped_size = dev_buffer.sz;
1724        }
1725
1726        ioctl_msg.in  = (void*)&dev_buffer;
1727        ioctl_msg.out = NULL;
1728
1729        DEBUG_PRINT_LOW("venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1730                dev_buffer.pbuffer, \
1731                dev_buffer.fd, \
1732                dev_buffer.offset, \
1733                dev_buffer.maped_size);
1734
1735        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0) {
1736            DEBUG_PRINT_ERROR("ERROR: venc_use_buf:set input buffer failed ");
1737            return false;
1738        }
1739    } else if (port == PORT_INDEX_OUT) {
1740        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1741        dev_buffer.fd  = pmem_tmp->fd;
1742        dev_buffer.sz = pmem_tmp->size;
1743        dev_buffer.maped_size = pmem_tmp->size;
1744        dev_buffer.offset = pmem_tmp->offset;
1745        ioctl_msg.in  = (void*)&dev_buffer;
1746        ioctl_msg.out = NULL;
1747
1748        DEBUG_PRINT_LOW("venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1749                dev_buffer.pbuffer, \
1750                dev_buffer.fd, \
1751                dev_buffer.offset, \
1752                dev_buffer.maped_size);
1753
1754        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0) {
1755            DEBUG_PRINT_ERROR("ERROR: venc_use_buf:set output buffer failed ");
1756            return false;
1757        }
1758    } else {
1759        DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
1760        return false;
1761    }
1762
1763    return true;
1764}
1765
1766bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
1767{
1768    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1769    struct pmem *pmem_tmp;
1770    struct venc_bufferpayload dev_buffer = {0};
1771
1772    pmem_tmp = (struct pmem *)buf_addr;
1773
1774    DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
1775
1776    if (port == PORT_INDEX_IN) {
1777        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1778        dev_buffer.fd  = pmem_tmp->fd;
1779        dev_buffer.maped_size = pmem_tmp->size;
1780        dev_buffer.sz = pmem_tmp->size;
1781        dev_buffer.offset = pmem_tmp->offset;
1782        ioctl_msg.in  = (void*)&dev_buffer;
1783        ioctl_msg.out = NULL;
1784
1785        DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1786                dev_buffer.pbuffer, \
1787                dev_buffer.fd, \
1788                dev_buffer.offset, \
1789                dev_buffer.maped_size);
1790
1791        if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0) {
1792            DEBUG_PRINT_ERROR("ERROR: venc_free_buf: free input buffer failed ");
1793            return false;
1794        }
1795    } else if (port == PORT_INDEX_OUT) {
1796        dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1797        dev_buffer.fd  = pmem_tmp->fd;
1798        dev_buffer.sz = pmem_tmp->size;
1799        dev_buffer.maped_size = pmem_tmp->size;
1800        dev_buffer.offset = pmem_tmp->offset;
1801        ioctl_msg.in  = (void*)&dev_buffer;
1802        ioctl_msg.out = NULL;
1803
1804        DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1805                dev_buffer.pbuffer, \
1806                dev_buffer.fd, \
1807                dev_buffer.offset, \
1808                dev_buffer.maped_size);
1809
1810        if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0) {
1811            DEBUG_PRINT_ERROR("ERROR: venc_free_buf: free output buffer failed ");
1812            return false;
1813        }
1814    } else {
1815        DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
1816        return false;
1817    }
1818
1819    return true;
1820}
1821
1822bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
1823                OMX_U32 width, OMX_U32 height)
1824{
1825    DEBUG_PRINT_ERROR("%s not implemented!", __func__);
1826    return OMX_ErrorUnsupportedSetting;
1827}
1828
1829bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
1830{
1831    struct venc_buffer frameinfo;
1832    struct pmem *temp_buffer;
1833    struct venc_ioctl_msg ioctl_msg;
1834    struct OMX_BUFFERHEADERTYPE *bufhdr;
1835
1836    if (buffer == NULL) {
1837        DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
1838        return false;
1839    }
1840
1841    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1842
1843    DEBUG_PRINT_LOW("Input buffer length %d",bufhdr->nFilledLen);
1844
1845    if (pmem_data_buf) {
1846        DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
1847        frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
1848    } else {
1849        DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1850        frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
1851    }
1852
1853    frameinfo.clientdata = (void *) buffer;
1854    frameinfo.sz = bufhdr->nFilledLen;
1855    frameinfo.len = bufhdr->nFilledLen;
1856    frameinfo.flags = bufhdr->nFlags;
1857    frameinfo.offset = bufhdr->nOffset;
1858    frameinfo.timestamp = bufhdr->nTimeStamp;
1859    DEBUG_PRINT_LOW("i/p TS = %u", (OMX_U32)frameinfo.timestamp);
1860    ioctl_msg.in = &frameinfo;
1861    ioctl_msg.out = NULL;
1862
1863    DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
1864            bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
1865
1866    if (ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) {
1867        /*Generate an async error and move to invalid state*/
1868        return false;
1869    }
1870
1871    if (m_debug.in_buffer_log) {
1872        venc_input_log_buffers(bufhdr, pmem_data_bufr, frameinfo.len);
1873    }
1874
1875    return true;
1876}
1877bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
1878{
1879    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1880    struct pmem *temp_buffer = NULL;
1881    struct venc_buffer  frameinfo;
1882    struct OMX_BUFFERHEADERTYPE *bufhdr;
1883
1884    if (buffer == NULL) {
1885        return false;
1886    }
1887
1888    bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1889
1890    if (pmem_data_buf) {
1891        DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
1892        frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
1893    } else {
1894        DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1895        frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
1896    }
1897
1898    frameinfo.clientdata = buffer;
1899    frameinfo.sz = bufhdr->nAllocLen;
1900    frameinfo.flags = bufhdr->nFlags;
1901    frameinfo.offset = bufhdr->nOffset;
1902
1903    ioctl_msg.in = &frameinfo;
1904    ioctl_msg.out = NULL;
1905    DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
1906            bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
1907
1908    if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) {
1909        DEBUG_PRINT_ERROR("ERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
1910        return false;
1911    }
1912
1913    return true;
1914}
1915
1916bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable)
1917{
1918    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1919    DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable);
1920
1921    if (multislice.mslice_mode == VEN_MSLICE_CNT_MB) {
1922        if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0) {
1923            DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
1924            return false;
1925        }
1926    } else {
1927        DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set "
1928                "slice delivery mode to the driver.", multislice.mslice_mode);
1929    }
1930
1931    return true;
1932}
1933
1934bool venc_dev::venc_set_plusptype(OMX_BOOL enable)
1935{
1936    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1937    struct venc_plusptype plusptype = {0};
1938    DEBUG_PRINT_LOW("Set plusptype: %d", enable);
1939    plusptype.plusptype_enable = enable;
1940    ioctl_msg.in = (void*)&plusptype;
1941    ioctl_msg.out = NULL;
1942
1943    if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0) {
1944        DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed");
1945        return false;
1946    }
1947
1948    return true;
1949}
1950
1951bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode)
1952{
1953    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1954    venc_ltrmode ltr_mode;
1955    ltr_mode.ltr_mode = (unsigned long)mode;
1956    DEBUG_PRINT_HIGH("Set ltr mode: %d", mode);
1957    ioctl_msg.in = (void*)&ltr_mode;
1958    ioctl_msg.out = NULL;
1959
1960    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0) {
1961        DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed");
1962        return false;
1963    }
1964
1965    ltrmode.ltr_mode = (unsigned long)mode;
1966    return true;
1967}
1968
1969bool venc_dev::venc_set_ltrcount(OMX_U32 count)
1970{
1971    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1972    venc_ltrcount ltr_count;
1973    ltr_count.ltr_count = (unsigned long)count;
1974    DEBUG_PRINT_HIGH("Set ltr count: %d", count);
1975    ioctl_msg.in = (void*)&ltr_count;
1976    ioctl_msg.out = NULL;
1977
1978    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0) {
1979        DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed");
1980        return false;
1981    }
1982
1983    ltrcount.ltr_count = (unsigned long)count;
1984    return true;
1985}
1986
1987bool venc_dev::venc_set_ltrperiod(OMX_U32 period)
1988{
1989    venc_ioctl_msg ioctl_msg = {NULL,NULL};
1990    venc_ltrperiod ltr_period;
1991    ltr_period.ltr_period = (unsigned long)period;
1992    DEBUG_PRINT_HIGH("Set ltr period: %d", period);
1993    ioctl_msg.in = (void*)&ltr_period;
1994    ioctl_msg.out = NULL;
1995
1996    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0) {
1997        DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed");
1998        return false;
1999    }
2000
2001    ltrperiod.ltr_period = (unsigned long)period;
2002    return true;
2003}
2004
2005bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames)
2006{
2007    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2008    venc_ltruse ltr_use;
2009    ltr_use.ltr_id = (unsigned long)id;
2010    ltr_use.ltr_frames = (unsigned long)frames;
2011    DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames);
2012    ioctl_msg.in = (void*)&ltr_use;
2013    ioctl_msg.out = NULL;
2014
2015    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0) {
2016        DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed");
2017        return false;
2018    }
2019
2020    return true;
2021}
2022
2023bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
2024{
2025    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2026    DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data);
2027    ioctl_msg.in = (void*)&extra_data;
2028    ioctl_msg.out = NULL;
2029
2030    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0) {
2031        DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
2032        return false;
2033    }
2034
2035    return true;
2036}
2037
2038bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
2039{
2040    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2041    struct venc_sessionqp qp = {0, 0};
2042    DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
2043            p_frame_qp);
2044
2045    qp.iframeqp = i_frame_qp;
2046    qp.pframqp = p_frame_qp;
2047
2048    ioctl_msg.in = (void*)&qp;
2049    ioctl_msg.out = NULL;
2050
2051    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0) {
2052        DEBUG_PRINT_ERROR("ERROR: Request for setting session qp failed");
2053        return false;
2054    }
2055
2056    session_qp.iframeqp = i_frame_qp;
2057    session_qp.pframqp = p_frame_qp;
2058
2059    return true;
2060}
2061
2062bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
2063{
2064    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2065    struct venc_qprange qp = {0, 0};
2066    DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp,
2067            max_qp);
2068
2069    qp.minqp = min_qp;
2070    qp.maxqp = max_qp;
2071
2072    ioctl_msg.in = (void*)&qp;
2073    ioctl_msg.out = NULL;
2074
2075    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0) {
2076        DEBUG_PRINT_ERROR("ERROR: Request for setting qp range failed");
2077        return false;
2078    }
2079
2080    qp_range.minqp= min_qp;
2081    qp_range.maxqp= max_qp;
2082
2083    return true;
2084}
2085
2086bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
2087{
2088    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2089    struct venc_profile requested_profile;
2090    struct ven_profilelevel requested_level;
2091    unsigned const int *profile_tbl = NULL;
2092    unsigned long mb_per_frame = 0, mb_per_sec = 0;
2093    DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d",
2094            eProfile, eLevel);
2095    mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
2096        ((m_sVenc_cfg.input_width + 15) >> 4);
2097
2098    if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
2099        DEBUG_PRINT_HIGH("Set profile/level was done already");
2100        return true;
2101    }
2102
2103    if (eProfile && eLevel) {
2104        /* non-zero values will be set by user, saving the same*/
2105        m_eProfile = eProfile;
2106        m_eLevel = eLevel;
2107        DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check",
2108                m_eProfile, m_eLevel);
2109    }
2110
2111    DEBUG_PRINT_LOW("Validating Profile/Level from table");
2112
2113    if (!venc_validate_profile_level(&eProfile, &eLevel)) {
2114        DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
2115        return false;
2116    }
2117
2118    if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) {
2119        DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
2120                "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
2121                OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
2122
2123        if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
2124            requested_profile.profile = VEN_PROFILE_MPEG4_SP;
2125            profile_tbl = (unsigned int const *)
2126                (&mpeg4_profile_level_table[MPEG4_SP_START]);
2127            profile_tbl += MPEG4_720P_LEVEL*5;
2128        } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
2129            requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
2130            profile_tbl = (unsigned int const *)
2131                (&mpeg4_profile_level_table[MPEG4_ASP_START]);
2132            profile_tbl += MPEG4_720P_LEVEL*5;
2133        } else {
2134            DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
2135                    eProfile);
2136            return false;
2137        }
2138
2139        DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
2140                "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
2141                "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
2142                OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
2143
2144        if (mb_per_frame >= 3600) {
2145            if (requested_profile.profile == VEN_PROFILE_MPEG4_ASP)
2146                requested_level.level = VEN_LEVEL_MPEG4_5;
2147
2148            if (requested_profile.profile == VEN_PROFILE_MPEG4_SP)
2149                requested_level.level = VEN_LEVEL_MPEG4_6;
2150        } else {
2151            switch (eLevel) {
2152                case OMX_VIDEO_MPEG4Level0:
2153                    requested_level.level = VEN_LEVEL_MPEG4_0;
2154                    break;
2155                case OMX_VIDEO_MPEG4Level1:
2156                    requested_level.level = VEN_LEVEL_MPEG4_1;
2157                    break;
2158                case OMX_VIDEO_MPEG4Level2:
2159                    requested_level.level = VEN_LEVEL_MPEG4_2;
2160                    break;
2161                case OMX_VIDEO_MPEG4Level3:
2162                    requested_level.level = VEN_LEVEL_MPEG4_3;
2163                    break;
2164                case OMX_VIDEO_MPEG4Level4a:
2165                    requested_level.level = VEN_LEVEL_MPEG4_4;
2166                    break;
2167                case OMX_VIDEO_MPEG4Level5:
2168                    mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
2169
2170                    if ((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) &&
2171                            (mb_per_sec >= profile_tbl[1])) {
2172                        DEBUG_PRINT_LOW("MPEG4 Level 6 is set for 720p resolution");
2173                        requested_level.level = VEN_LEVEL_MPEG4_6;
2174                    } else {
2175                        DEBUG_PRINT_LOW("MPEG4 Level 5 is set for non-720p resolution");
2176                        requested_level.level = VEN_LEVEL_MPEG4_5;
2177                    }
2178
2179                    break;
2180                default:
2181                    return false;
2182                    // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
2183                    break;
2184            }
2185        }
2186    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) {
2187        if (eProfile == OMX_VIDEO_H263ProfileBaseline) {
2188            requested_profile.profile = VEN_PROFILE_H263_BASELINE;
2189        } else {
2190            DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %u",
2191                    requested_profile.profile);
2192            return false;
2193        }
2194
2195        //profile level
2196        switch (eLevel) {
2197            case OMX_VIDEO_H263Level10:
2198                requested_level.level = VEN_LEVEL_H263_10;
2199                break;
2200            case OMX_VIDEO_H263Level20:
2201                requested_level.level = VEN_LEVEL_H263_20;
2202                break;
2203            case OMX_VIDEO_H263Level30:
2204                requested_level.level = VEN_LEVEL_H263_30;
2205                break;
2206            case OMX_VIDEO_H263Level40:
2207                requested_level.level = VEN_LEVEL_H263_40;
2208                break;
2209            case OMX_VIDEO_H263Level45:
2210                requested_level.level = VEN_LEVEL_H263_45;
2211                break;
2212            case OMX_VIDEO_H263Level50:
2213                requested_level.level = VEN_LEVEL_H263_50;
2214                break;
2215            case OMX_VIDEO_H263Level60:
2216                requested_level.level = VEN_LEVEL_H263_60;
2217                break;
2218            case OMX_VIDEO_H263Level70:
2219                requested_level.level = VEN_LEVEL_H263_70;
2220                break;
2221            default:
2222                return false;
2223                break;
2224        }
2225    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) {
2226        if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
2227            requested_profile.profile = VEN_PROFILE_H264_BASELINE;
2228        } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
2229            requested_profile.profile = VEN_PROFILE_H264_MAIN;
2230        } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
2231            requested_profile.profile = VEN_PROFILE_H264_HIGH;
2232        } else {
2233            DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %u",
2234                    requested_profile.profile);
2235            return false;
2236        }
2237
2238        //profile level
2239        switch (eLevel) {
2240            case OMX_VIDEO_AVCLevel1:
2241                requested_level.level = VEN_LEVEL_H264_1;
2242                break;
2243            case OMX_VIDEO_AVCLevel1b:
2244                requested_level.level = VEN_LEVEL_H264_1b;
2245                break;
2246            case OMX_VIDEO_AVCLevel11:
2247                requested_level.level = VEN_LEVEL_H264_1p1;
2248                break;
2249            case OMX_VIDEO_AVCLevel12:
2250                requested_level.level = VEN_LEVEL_H264_1p2;
2251                break;
2252            case OMX_VIDEO_AVCLevel13:
2253                requested_level.level = VEN_LEVEL_H264_1p3;
2254                break;
2255            case OMX_VIDEO_AVCLevel2:
2256                requested_level.level = VEN_LEVEL_H264_2;
2257                break;
2258            case OMX_VIDEO_AVCLevel21:
2259                requested_level.level = VEN_LEVEL_H264_2p1;
2260                break;
2261            case OMX_VIDEO_AVCLevel22:
2262                requested_level.level = VEN_LEVEL_H264_2p2;
2263                break;
2264            case OMX_VIDEO_AVCLevel3:
2265                requested_level.level = VEN_LEVEL_H264_3;
2266                break;
2267            case OMX_VIDEO_AVCLevel31:
2268                requested_level.level = VEN_LEVEL_H264_3p1;
2269                break;
2270            case OMX_VIDEO_AVCLevel32:
2271                requested_level.level = VEN_LEVEL_H264_3p2;
2272                break;
2273            case OMX_VIDEO_AVCLevel4:
2274                requested_level.level = VEN_LEVEL_H264_4;
2275                break;
2276            default :
2277                DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %u",
2278                        requested_level.level);
2279                return false;
2280                break;
2281        }
2282    }
2283
2284    if (!m_profile_set) {
2285        ioctl_msg.in = (void*)&requested_profile;
2286        ioctl_msg.out = NULL;
2287
2288        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0) {
2289            DEBUG_PRINT_ERROR("ERROR: Request for setting profile failed");
2290            return false;
2291        }
2292
2293        codec_profile.profile = requested_profile.profile;
2294        m_profile_set = true;
2295        DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile);
2296    }
2297
2298    if (!m_level_set) {
2299        ioctl_msg.in = (void*)&requested_level;
2300        ioctl_msg.out = NULL;
2301
2302        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0) {
2303            DEBUG_PRINT_ERROR("ERROR: Request for setting profile level failed");
2304            return false;
2305        }
2306
2307        profile_level.level = requested_level.level;
2308        m_level_set = true;
2309        DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level);
2310    }
2311
2312    return true;
2313}
2314
2315bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
2316{
2317    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2318    struct venc_voptimingcfg vop_timing_cfg;
2319
2320    DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u",
2321            TimeIncRes);
2322
2323    vop_timing_cfg.voptime_resolution = TimeIncRes;
2324
2325    ioctl_msg.in = (void*)&vop_timing_cfg;
2326    ioctl_msg.out = NULL;
2327
2328    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0) {
2329        DEBUG_PRINT_ERROR("ERROR: Request for setting Vop Timing failed");
2330        return false;
2331    }
2332
2333    voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
2334    return true;
2335}
2336
2337bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
2338{
2339    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2340    struct venc_intraperiod intraperiod_cfg;
2341
2342    DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u",
2343            nPFrames);
2344    intraperiod_cfg.num_pframes = nPFrames;
2345
2346    if ((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) ||
2347            (codec_profile.profile == VEN_PROFILE_H264_MAIN) ||
2348            (codec_profile.profile == VEN_PROFILE_H264_HIGH)) {
2349#ifdef MAX_RES_1080P
2350
2351        if (nBFrames) {
2352            DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
2353            intraperiod_cfg.num_bframes = 1;
2354        } else
2355            intraperiod_cfg.num_bframes = 0;
2356
2357#else
2358
2359        if (nBFrames) {
2360            DEBUG_PRINT_ERROR("B frames not supported");
2361            intraperiod_cfg.num_bframes = 0;
2362        } else {
2363            DEBUG_PRINT_ERROR("B frames not supported");
2364            intraperiod_cfg.num_bframes = 0;
2365        }
2366
2367#endif
2368    } else
2369        intraperiod_cfg.num_bframes = 0;
2370
2371    DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u",
2372            intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes);
2373    ioctl_msg.in = (void*)&intraperiod_cfg;
2374    ioctl_msg.out = NULL;
2375
2376    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0) {
2377        DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
2378        return false;
2379    }
2380
2381    intra_period.num_pframes = intraperiod_cfg.num_pframes;
2382    intra_period.num_bframes = intraperiod_cfg.num_bframes;
2383    return true;
2384}
2385
2386bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
2387{
2388    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2389    struct venc_entropycfg entropy_cfg;
2390
2391    memset(&entropy_cfg,0,sizeof(entropy_cfg));
2392    DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
2393
2394    if (enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)) {
2395        entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC;
2396
2397        if (i_cabac_level == 0) {
2398            entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
2399        }
2400
2401#ifdef MAX_RES_1080P
2402        else {
2403            DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to  model 0",i_cabac_level);
2404            entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
2405        }
2406
2407#else
2408        else if (i_cabac_level == 1) {
2409            entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1;
2410        } else if (i_cabac_level == 2) {
2411            entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2;
2412        }
2413
2414#endif
2415    } else if (!enable) {
2416        entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC;
2417    } else {
2418        DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
2419        return false;
2420    }
2421
2422    ioctl_msg.in = (void*)&entropy_cfg;
2423    ioctl_msg.out = NULL;
2424
2425    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0) {
2426        DEBUG_PRINT_ERROR("ERROR: Request for setting entropy config failed");
2427        return false;
2428    }
2429
2430    entropy.longentropysel = entropy_cfg.longentropysel;
2431    entropy.cabacmodel  = entropy_cfg.cabacmodel;
2432    return true;
2433}
2434
2435bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
2436{
2437    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2438    bool status = true;
2439    struct venc_multiclicecfg multislice_cfg;
2440
2441    if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
2442        multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
2443        multislice_cfg.mslice_size = nSlicesize;
2444    } else {
2445        multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
2446        multislice_cfg.mslice_size = 0;
2447    }
2448
2449    DEBUG_PRINT_LOW("%s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
2450            multislice_cfg.mslice_size);
2451
2452    ioctl_msg.in = (void*)&multislice_cfg;
2453    ioctl_msg.out = NULL;
2454
2455    if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
2456        DEBUG_PRINT_ERROR("ERROR: Request for setting multi-slice cfg failed");
2457        status = false;
2458    } else {
2459        multislice.mslice_mode = multislice_cfg.mslice_mode;
2460        multislice.mslice_size = nSlicesize;
2461    }
2462
2463    return status;
2464}
2465
2466bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
2467{
2468    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2469    bool status = true;
2470    struct venc_intrarefresh intraRefresh_cfg;
2471
2472    // There is no disabled mode.  Disabled mode is indicated by a 0 count.
2473    if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
2474        intraRefresh_cfg.irmode = VEN_IR_OFF;
2475        intraRefresh_cfg.mbcount = 0;
2476    } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
2477            (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) {
2478        intraRefresh_cfg.irmode = VEN_IR_CYCLIC;
2479        intraRefresh_cfg.mbcount = irMBs;
2480    } else {
2481        DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
2482                "mb count: %d, mb mode:%d", irMBs, ir_mode);
2483        return false;
2484    }
2485
2486    ioctl_msg.in = (void*)&intraRefresh_cfg;
2487    ioctl_msg.out = NULL;
2488
2489    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0) {
2490        DEBUG_PRINT_ERROR("ERROR: Request for setting Intra Refresh failed");
2491        status = false;
2492    } else {
2493        intra_refresh.irmode = intraRefresh_cfg.irmode;
2494        intra_refresh.mbcount = intraRefresh_cfg.mbcount;
2495    }
2496
2497    return status;
2498}
2499
2500bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
2501{
2502    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2503    bool status = true;
2504    struct venc_headerextension hec_cfg;
2505    struct venc_multiclicecfg multislice_cfg;
2506
2507    if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) {
2508        if (error_resilience->bEnableHEC) {
2509            hec_cfg.header_extension = 1;
2510        } else {
2511            hec_cfg.header_extension = 0;
2512        }
2513
2514        ioctl_msg.in = (void*)&hec_cfg;
2515        ioctl_msg.out = NULL;
2516
2517        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) {
2518            DEBUG_PRINT_ERROR("ERROR: Request for setting HEader Error correction failed");
2519            return false;
2520        }
2521
2522        hec.header_extension = error_resilience->bEnableHEC;
2523    }
2524
2525    if (error_resilience->bEnableRVLC) {
2526        DEBUG_PRINT_ERROR("RVLC is not Supported");
2527        return false;
2528    }
2529
2530    if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
2531            (error_resilience->bEnableDataPartitioning)) {
2532        DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
2533        return false;
2534    }
2535
2536    if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
2537            (error_resilience->nResynchMarkerSpacing)) {
2538        multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
2539        multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
2540    } else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
2541            error_resilience->bEnableDataPartitioning) {
2542        multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
2543        multislice_cfg.mslice_size = 0;
2544    } else {
2545        multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
2546        multislice_cfg.mslice_size = 0;
2547    }
2548
2549    DEBUG_PRINT_LOW("%s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
2550            multislice_cfg.mslice_size);
2551    ioctl_msg.in = (void*)&multislice_cfg;
2552    ioctl_msg.out = NULL;
2553
2554    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
2555        DEBUG_PRINT_ERROR("ERROR: Request for setting multi-slice cfg failed");
2556        status = false;
2557    } else {
2558        multislice.mslice_mode = multislice_cfg.mslice_mode ;
2559        multislice.mslice_size = multislice_cfg.mslice_size;
2560
2561    }
2562
2563    return status;
2564}
2565
2566bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
2567{
2568    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2569    struct venc_dbcfg filter_cfg;
2570
2571    memset(&filter_cfg, 0, sizeof(filter_cfg));
2572    DEBUG_PRINT_LOW("venc_set_inloop_filter: %u",loopfilter);
2573
2574    if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
2575        filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY;
2576    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
2577        filter_cfg.db_mode = VEN_DB_DISABLE;
2578    } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
2579        filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY;
2580    }
2581
2582    filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0;
2583
2584    ioctl_msg.in = (void*)&filter_cfg;
2585    ioctl_msg.out = NULL;
2586
2587    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0) {
2588        DEBUG_PRINT_ERROR("ERROR: Request for setting inloop filter failed");
2589        return false;
2590    }
2591
2592    dbkfilter.db_mode = filter_cfg.db_mode;
2593    dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
2594    return true;
2595}
2596
2597bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
2598{
2599    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2600    struct venc_targetbitrate bitrate_cfg;
2601
2602    DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u",
2603            nTargetBitrate);
2604    bitrate_cfg.target_bitrate = nTargetBitrate ;
2605    ioctl_msg.in = (void*)&bitrate_cfg;
2606    ioctl_msg.out = NULL;
2607
2608    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0) {
2609        DEBUG_PRINT_ERROR("ERROR: Request for setting bit rate failed");
2610        return false;
2611    }
2612
2613    m_sVenc_cfg.targetbitrate = nTargetBitrate;
2614    bitrate.target_bitrate = nTargetBitrate;
2615
2616    if (!config) {
2617        m_level_set = false;
2618
2619        if (venc_set_profile_level(0, 0)) {
2620            DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d",profile_level.level);
2621        }
2622    }
2623
2624    return true;
2625}
2626
2627bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
2628{
2629    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2630    struct venc_framerate frame_rate_cfg;
2631
2632    Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
2633
2634    DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d",
2635            encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
2636
2637    ioctl_msg.in = (void*)&frame_rate_cfg;
2638    ioctl_msg.out = NULL;
2639
2640    if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
2641                (void*)&ioctl_msg) < 0) {
2642        DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
2643        return false;
2644    }
2645
2646    m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
2647    m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
2648
2649    if (!config) {
2650        m_level_set = false;
2651
2652        if (venc_set_profile_level(0, 0)) {
2653            DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level);
2654        }
2655    }
2656
2657    return true;
2658}
2659
2660bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
2661{
2662    venc_ioctl_msg ioctl_msg = {NULL, NULL};
2663
2664    if (color_format == OMX_COLOR_FormatYUV420SemiPlanar) {
2665#ifdef MAX_RES_1080P
2666        m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
2667#else
2668        m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
2669#endif
2670    } else {
2671        DEBUG_PRINT_ERROR("WARNING: Unsupported Color format [%d]", color_format);
2672#ifdef MAX_RES_1080P
2673        m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
2674#else
2675        m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
2676#endif
2677        DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
2678    }
2679
2680    ioctl_msg.in = (void*)&m_sVenc_cfg;
2681    ioctl_msg.out = NULL;
2682
2683    if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0) {
2684        DEBUG_PRINT_ERROR("ERROR: Request for setting color format failed");
2685        return false;
2686    }
2687
2688    return true;
2689}
2690
2691bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
2692{
2693    DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
2694
2695    if (intra_vop_refresh == OMX_TRUE) {
2696        if (ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0) {
2697            DEBUG_PRINT_ERROR("ERROR: Request for setting Intra VOP Refresh failed");
2698            return false;
2699        }
2700    } else {
2701        DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
2702    }
2703
2704    return true;
2705}
2706
2707bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
2708{
2709    venc_ioctl_msg ioctl_msg = {NULL,NULL};
2710    bool status = true;
2711    struct venc_ratectrlcfg ratectrl_cfg;
2712
2713    //rate control
2714    switch (eControlRate) {
2715        case OMX_Video_ControlRateDisable:
2716            ratectrl_cfg.rcmode = VEN_RC_OFF;
2717            break;
2718        case OMX_Video_ControlRateVariableSkipFrames:
2719            ratectrl_cfg.rcmode = VEN_RC_VBR_VFR;
2720            break;
2721        case OMX_Video_ControlRateVariable:
2722            ratectrl_cfg.rcmode = VEN_RC_VBR_CFR;
2723            break;
2724        case OMX_Video_ControlRateConstantSkipFrames:
2725            ratectrl_cfg.rcmode = VEN_RC_CBR_VFR;
2726            break;
2727        case OMX_Video_ControlRateConstant:
2728            ratectrl_cfg.rcmode = VEN_RC_CBR_CFR;
2729            break;
2730        default:
2731            status = false;
2732            break;
2733    }
2734
2735    if (status) {
2736        ioctl_msg.in = (void*)&ratectrl_cfg;
2737        ioctl_msg.out = NULL;
2738
2739        if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0) {
2740            DEBUG_PRINT_ERROR("ERROR: Request for setting rate control failed");
2741            status = false;
2742        } else
2743            rate_ctrl.rcmode = ratectrl_cfg.rcmode;
2744    }
2745
2746    return status;
2747}
2748
2749bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
2750{
2751    bool status = true;
2752
2753    if (eProfile == NULL || eLevel == NULL) {
2754        return false;
2755    }
2756
2757    if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) {
2758        switch (codec_profile.profile) {
2759            case VEN_PROFILE_MPEG4_SP:
2760                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2761                break;
2762            case VEN_PROFILE_MPEG4_ASP:
2763                *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2764                break;
2765            default:
2766                *eProfile = OMX_VIDEO_MPEG4ProfileMax;
2767                status = false;
2768                break;
2769        }
2770
2771        if (!status) {
2772            return status;
2773        }
2774
2775        //profile level
2776        switch (profile_level.level) {
2777            case VEN_LEVEL_MPEG4_0:
2778                *eLevel = OMX_VIDEO_MPEG4Level0;
2779                break;
2780            case VEN_LEVEL_MPEG4_1:
2781                *eLevel = OMX_VIDEO_MPEG4Level1;
2782                break;
2783            case VEN_LEVEL_MPEG4_2:
2784                *eLevel = OMX_VIDEO_MPEG4Level2;
2785                break;
2786            case VEN_LEVEL_MPEG4_3:
2787                *eLevel = OMX_VIDEO_MPEG4Level3;
2788                break;
2789            case VEN_LEVEL_MPEG4_4:
2790                *eLevel = OMX_VIDEO_MPEG4Level4a;
2791                break;
2792            case VEN_LEVEL_MPEG4_5:
2793            case VEN_LEVEL_MPEG4_6:
2794                *eLevel = OMX_VIDEO_MPEG4Level5;
2795                break;
2796            default:
2797                *eLevel = OMX_VIDEO_MPEG4LevelMax;
2798                status =  false;
2799                break;
2800        }
2801    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) {
2802        if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
2803            *eProfile = OMX_VIDEO_H263ProfileBaseline;
2804        } else {
2805            *eProfile = OMX_VIDEO_H263ProfileMax;
2806            return false;
2807        }
2808
2809        switch (profile_level.level) {
2810            case VEN_LEVEL_H263_10:
2811                *eLevel = OMX_VIDEO_H263Level10;
2812                break;
2813            case VEN_LEVEL_H263_20:
2814                *eLevel = OMX_VIDEO_H263Level20;
2815                break;
2816            case VEN_LEVEL_H263_30:
2817                *eLevel = OMX_VIDEO_H263Level30;
2818                break;
2819            case VEN_LEVEL_H263_40:
2820                *eLevel = OMX_VIDEO_H263Level40;
2821                break;
2822            case VEN_LEVEL_H263_45:
2823                *eLevel = OMX_VIDEO_H263Level45;
2824                break;
2825            case VEN_LEVEL_H263_50:
2826                *eLevel = OMX_VIDEO_H263Level50;
2827                break;
2828            case VEN_LEVEL_H263_60:
2829                *eLevel = OMX_VIDEO_H263Level60;
2830                break;
2831            case VEN_LEVEL_H263_70:
2832                *eLevel = OMX_VIDEO_H263Level70;
2833                break;
2834            default:
2835                *eLevel = OMX_VIDEO_H263LevelMax;
2836                status = false;
2837                break;
2838        }
2839    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) {
2840        switch (codec_profile.profile) {
2841            case VEN_PROFILE_H264_BASELINE:
2842                *eProfile = OMX_VIDEO_AVCProfileBaseline;
2843                break;
2844            case VEN_PROFILE_H264_MAIN:
2845                *eProfile = OMX_VIDEO_AVCProfileMain;
2846                break;
2847            case VEN_PROFILE_H264_HIGH:
2848                *eProfile = OMX_VIDEO_AVCProfileHigh;
2849                break;
2850            default:
2851                *eProfile = OMX_VIDEO_AVCProfileMax;
2852                status = false;
2853                break;
2854        }
2855
2856        if (!status) {
2857            return status;
2858        }
2859
2860        switch (profile_level.level) {
2861            case VEN_LEVEL_H264_1:
2862                *eLevel = OMX_VIDEO_AVCLevel1;
2863                break;
2864            case VEN_LEVEL_H264_1b:
2865                *eLevel = OMX_VIDEO_AVCLevel1b;
2866                break;
2867            case VEN_LEVEL_H264_1p1:
2868                *eLevel = OMX_VIDEO_AVCLevel11;
2869                break;
2870            case VEN_LEVEL_H264_1p2:
2871                *eLevel = OMX_VIDEO_AVCLevel12;
2872                break;
2873            case VEN_LEVEL_H264_1p3:
2874                *eLevel = OMX_VIDEO_AVCLevel13;
2875                break;
2876            case VEN_LEVEL_H264_2:
2877                *eLevel = OMX_VIDEO_AVCLevel2;
2878                break;
2879            case VEN_LEVEL_H264_2p1:
2880                *eLevel = OMX_VIDEO_AVCLevel21;
2881                break;
2882            case VEN_LEVEL_H264_2p2:
2883                *eLevel = OMX_VIDEO_AVCLevel22;
2884                break;
2885            case VEN_LEVEL_H264_3:
2886                *eLevel = OMX_VIDEO_AVCLevel3;
2887                break;
2888            case VEN_LEVEL_H264_3p1:
2889                *eLevel = OMX_VIDEO_AVCLevel31;
2890                break;
2891            case VEN_LEVEL_H264_3p2:
2892                *eLevel = OMX_VIDEO_AVCLevel32;
2893                break;
2894            case VEN_LEVEL_H264_4:
2895                *eLevel = OMX_VIDEO_AVCLevel4;
2896                break;
2897            default :
2898                *eLevel = OMX_VIDEO_AVCLevelMax;
2899                status = false;
2900                break;
2901        }
2902    }
2903
2904    return status;
2905}
2906
2907bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
2908{
2909    OMX_U32 new_profile = 0, new_level = 0;
2910    unsigned const int *profile_tbl = NULL;
2911    OMX_U32 mb_per_frame, mb_per_sec;
2912    bool profile_level_found = false;
2913
2914    DEBUG_PRINT_LOW("Init profile table for respective codec");
2915
2916    //validate the ht,width,fps,bitrate and set the appropriate profile and level
2917    if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) {
2918        if (*eProfile == 0) {
2919            if (!m_profile_set) {
2920                *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2921            } else {
2922                switch (codec_profile.profile) {
2923                    case VEN_PROFILE_MPEG4_ASP:
2924                        *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2925                        break;
2926                    case VEN_PROFILE_MPEG4_SP:
2927                        *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2928                        break;
2929                    default:
2930                        DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
2931                        return false;
2932                }
2933            }
2934        }
2935
2936        if (*eLevel == 0 && !m_level_set) {
2937            *eLevel = OMX_VIDEO_MPEG4LevelMax;
2938        }
2939
2940        if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
2941            profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
2942        } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
2943            profile_tbl = (unsigned int const *)
2944                (&mpeg4_profile_level_table[MPEG4_ASP_START]);
2945        } else {
2946            DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %lu", *eProfile);
2947            return false;
2948        }
2949    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) {
2950        if (*eProfile == 0) {
2951            if (!m_profile_set) {
2952                *eProfile = OMX_VIDEO_AVCProfileBaseline;
2953            } else {
2954                switch (codec_profile.profile) {
2955                    case VEN_PROFILE_H264_BASELINE:
2956                        *eProfile = OMX_VIDEO_AVCProfileBaseline;
2957                        break;
2958#ifndef _MSM8610_
2959                    case VEN_PROFILE_H264_MAIN:
2960                        *eProfile = OMX_VIDEO_AVCProfileMain;
2961                        break;
2962                    case VEN_PROFILE_H264_HIGH:
2963                        *eProfile = OMX_VIDEO_AVCProfileHigh;
2964                        break;
2965#endif
2966                    default:
2967                        DEBUG_PRINT_LOW("%s(): Unsupported profile %x", __func__, codec_profile.profile);
2968                        return false;
2969                }
2970            }
2971        }
2972
2973        if (*eLevel == 0 && !m_level_set) {
2974            *eLevel = OMX_VIDEO_AVCLevelMax;
2975        }
2976
2977        if (*eProfile == OMX_VIDEO_AVCProfileBaseline) {
2978            profile_tbl = (unsigned int const *)h264_profile_level_table;
2979        } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
2980            profile_tbl = (unsigned int const *)
2981                (&h264_profile_level_table[H264_HP_START]);
2982        } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
2983            profile_tbl = (unsigned int const *)
2984                (&h264_profile_level_table[H264_MP_START]);
2985        } else {
2986            DEBUG_PRINT_LOW("Unsupported AVC profile type %lu", *eProfile);
2987            return false;
2988        }
2989    } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) {
2990        if (*eProfile == 0) {
2991            if (!m_profile_set) {
2992                *eProfile = OMX_VIDEO_H263ProfileBaseline;
2993            } else {
2994                switch (codec_profile.profile) {
2995                    case VEN_PROFILE_H263_BASELINE:
2996                        *eProfile = OMX_VIDEO_H263ProfileBaseline;
2997                        break;
2998                    default:
2999                        DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
3000                        return false;
3001                }
3002            }
3003        }
3004
3005        if (*eLevel == 0 && !m_level_set) {
3006            *eLevel = OMX_VIDEO_H263LevelMax;
3007        }
3008
3009        if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
3010            profile_tbl = (unsigned int const *)h263_profile_level_table;
3011        } else {
3012            DEBUG_PRINT_LOW("Unsupported H.263 profile type %lu", *eProfile);
3013            return false;
3014        }
3015    } else {
3016        DEBUG_PRINT_LOW("Invalid codec type");
3017        return false;
3018    }
3019
3020    mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
3021        ((m_sVenc_cfg.input_width + 15)>> 4);
3022
3023    if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)) {
3024        if (codec_profile.profile == VEN_PROFILE_MPEG4_ASP)
3025            profile_level.level = VEN_LEVEL_MPEG4_5;
3026
3027        if (codec_profile.profile == VEN_PROFILE_MPEG4_SP)
3028            profile_level.level = VEN_LEVEL_MPEG4_6;
3029
3030        {
3031            new_level = profile_level.level;
3032            new_profile = codec_profile.profile;
3033            return true;
3034        }
3035    }
3036
3037    mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
3038
3039    do {
3040        if (mb_per_frame <= (int)profile_tbl[0]) {
3041            if (mb_per_sec <= (int)profile_tbl[1]) {
3042                if (m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2]) {
3043                    new_level = (int)profile_tbl[3];
3044                    new_profile = (int)profile_tbl[4];
3045                    profile_level_found = true;
3046                    DEBUG_PRINT_LOW("Appropriate profile/level found %d/%d", new_profile, new_level);
3047                    break;
3048                }
3049            }
3050        }
3051
3052        profile_tbl = profile_tbl + 5;
3053    } while (profile_tbl[0] != 0);
3054
3055    if (profile_level_found != true) {
3056        DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
3057        return false;
3058    }
3059
3060    if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
3061            || (*eLevel == OMX_VIDEO_H263LevelMax)) {
3062        *eLevel = new_level;
3063    }
3064
3065    DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu"
3066            "Level = %lu", __func__, *eProfile, *eLevel);
3067
3068    return true;
3069}
3070
3071bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate)
3072{
3073    unsigned const int *profile_tbl = NULL;
3074
3075    switch (m_sVenc_cfg.codectype) {
3076        case VEN_CODEC_MPEG4:
3077
3078            if (m_eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
3079                profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
3080            } else if (m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
3081                profile_tbl = (unsigned int const *)
3082                    (&mpeg4_profile_level_table[MPEG4_ASP_START]);
3083            } else {
3084                DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile);
3085                return false;
3086            }
3087
3088            break;
3089        case VEN_CODEC_H264:
3090
3091            if (m_eProfile == OMX_VIDEO_AVCProfileBaseline) {
3092                profile_tbl = (unsigned int const *)h264_profile_level_table;
3093            } else if (m_eProfile == OMX_VIDEO_AVCProfileHigh) {
3094                profile_tbl = (unsigned int const *)
3095                    (&h264_profile_level_table[H264_HP_START]);
3096            } else if (m_eProfile == OMX_VIDEO_AVCProfileMain) {
3097                profile_tbl = (unsigned int const *)
3098                    (&h264_profile_level_table[H264_MP_START]);
3099            } else {
3100                DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile);
3101                return false;
3102            }
3103
3104            break;
3105        case VEN_CODEC_H263:
3106
3107            if (m_eProfile == OMX_VIDEO_H263ProfileBaseline) {
3108                profile_tbl = (unsigned int const *)h263_profile_level_table;
3109            } else {
3110                DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile);
3111                return false;
3112            }
3113
3114            break;
3115        default:
3116            DEBUG_PRINT_ERROR("%s: unknown codec type", __func__);
3117            return false;
3118    }
3119
3120    while (profile_tbl[0] != 0) {
3121        if (profile_tbl[3] == m_eLevel) {
3122            if (nTargetBitrate > profile_tbl[2]) {
3123                DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]"
3124                        " is %u", m_eProfile, m_eLevel, profile_tbl[2]);
3125                return false;
3126            }
3127        }
3128
3129        profile_tbl += 5;
3130    }
3131
3132    return true;
3133}
3134
3135#ifdef _ANDROID_ICS_
3136bool venc_dev::venc_set_meta_mode(bool mode)
3137{
3138    venc_ioctl_msg ioctl_msg = {NULL,NULL};
3139    ioctl_msg.in = &mode;
3140    DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode);
3141
3142    if (ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0) {
3143        DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
3144        return false;
3145    }
3146
3147    return true;
3148}
3149#endif
3150