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