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