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