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