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