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