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