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