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