• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*--------------------------------------------------------------------------
2 Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED 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*/
50 static 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*/
72 static 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*/
120 static 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
138 FILE *inputBufferFile1;
139 char inputfilename [] = "/data/input.yuv";
140 #endif
141 #ifdef OUTPUT_BUFFER_LOG
142 FILE *outputBufferFile1;
143 char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
144 #endif
145 //constructor
venc_dev(class omx_venc * venc_class)146 venc_dev::venc_dev(class omx_venc *venc_class)
147 {
148 //nothing to do
149 venc_handle = venc_class;
150 etb_count=0;
151 }
152 
~venc_dev()153 venc_dev::~venc_dev()
154 {
155   //nothing to do
156 }
157 
async_venc_message_thread(void * input)158 void* 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 
venc_open(OMX_U32 codec)239 bool 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 
venc_close()420 void 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 
venc_set_buf_req(unsigned long * min_buff_count,unsigned long * actual_buff_count,unsigned long * buff_size,unsigned long port)463 bool 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 
venc_loaded_start()506 bool venc_dev::venc_loaded_start()
507 {
508   return true;
509 }
510 
venc_loaded_stop()511 bool venc_dev::venc_loaded_stop()
512 {
513   return true;
514 }
515 
venc_loaded_start_done()516 bool venc_dev::venc_loaded_start_done()
517 {
518   return true;
519 }
520 
venc_loaded_stop_done()521 bool venc_dev::venc_loaded_stop_done()
522 {
523   return true;
524 }
525 
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)526 bool venc_dev::venc_get_seq_hdr(void *buffer,
527     unsigned buffer_size, unsigned *header_len)
528 {
529   return true;
530 }
531 
venc_get_buf_req(unsigned long * min_buff_count,unsigned long * actual_buff_count,unsigned long * buff_size,unsigned long port)532 bool 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 
556 bufreq.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 
venc_set_param(void * paramData,OMX_INDEXTYPE index)610 bool 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 
venc_set_config(void * configData,OMX_INDEXTYPE index)1043 bool 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 
venc_stop(void)1146 unsigned venc_dev::venc_stop( void)
1147 {
1148     pmem_free();
1149   return 0;
1150 }
1151 
venc_pause(void)1152 unsigned venc_dev::venc_pause(void)
1153 {
1154   return 0;
1155 }
1156 
venc_resume(void)1157 unsigned venc_dev::venc_resume(void)
1158 {
1159   return 0;
1160 }
1161 
venc_start_done(void)1162 unsigned 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 
venc_stop_done(void)1171 unsigned 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 
venc_start(void)1180 unsigned 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 
pmem_allocate(OMX_U32 size,OMX_U32 alignment,OMX_U32 count)1219 OMX_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 
pmem_free()1326 OMX_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 }
venc_config_print()1362 void 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 
venc_flush(unsigned port)1393 unsigned 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 
venc_use_buf(void * buf_addr,unsigned port,unsigned index)1435 bool 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 
venc_free_buf(void * buf_addr,unsigned port)1510 bool 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 
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)1567 bool 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 
1586 DEBUG_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 }
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)1654 bool 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 
1670 if(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 
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)1708 bool 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 
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)1764 bool 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 
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)2058 bool 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 
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)2078 bool 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 
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)2123 bool 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 
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)2195 bool 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 
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)2251 bool 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 
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)2317 bool 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 
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)2378 bool 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 
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)2431 bool 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 
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)2467 bool 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 
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)2501 bool 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 
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)2523 bool 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 
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)2541 bool 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 
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)2592 bool 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 
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)2789 bool 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_
venc_set_meta_mode(bool mode)3004 bool 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