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