blob: 7b56d33a6499ace1df527e7577b4e7723d1e83d0 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Duy Truong364dffd2013-02-10 04:33:57 -08002Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
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.
Duy Truong364dffd2013-02-10 04:33:57 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 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
Arun Menona7881862012-09-11 14:24:16 -070037#include <linux/msm_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 {
Rajeshwar Kurapaty21459eb2012-08-16 17:14:54 -0700185 DEBUG_PRINT_LOW("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700186 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
Rajeshwar Kurapatyd60e2592012-10-08 15:59:09 +0530246// initializing QP range parameters
247 qp_range.minqp = 2;
248 if(codec == OMX_VIDEO_CodingAVC)
249 qp_range.maxqp = 51;
250 else
251 qp_range.maxqp = 31;
252
Shalaj Jain273b3e02012-06-22 19:08:03 -0700253 if(codec == OMX_VIDEO_CodingMPEG4)
254 {
255 m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
256 codec_profile.profile = VEN_PROFILE_MPEG4_SP;
257 profile_level.level = VEN_LEVEL_MPEG4_2;
258#ifdef OUTPUT_BUFFER_LOG
259 strcat(outputfilename, "m4v");
260#endif
261 }
262 else if(codec == OMX_VIDEO_CodingH263)
263 {
264 m_sVenc_cfg.codectype = VEN_CODEC_H263;
265 codec_profile.profile = VEN_PROFILE_H263_BASELINE;
266 profile_level.level = VEN_LEVEL_H263_20;
267#ifdef OUTPUT_BUFFER_LOG
268 strcat(outputfilename, "263");
269#endif
270 }
271 if(codec == OMX_VIDEO_CodingAVC)
272 {
273 m_sVenc_cfg.codectype = VEN_CODEC_H264;
274 codec_profile.profile = VEN_PROFILE_H264_BASELINE;
275 profile_level.level = VEN_LEVEL_H264_1p1;
276#ifdef OUTPUT_BUFFER_LOG
277 strcat(outputfilename, "264");
278#endif
279 }
280 ioctl_msg.in = (void*)&m_sVenc_cfg;
281 ioctl_msg.out = NULL;
282 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 )
283 {
284 DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
285 return false;
286 }
287#ifdef INPUT_BUFFER_LOG
288 inputBufferFile1 = fopen (inputfilename, "ab");
289#endif
290#ifdef OUTPUT_BUFFER_LOG
291 outputBufferFile1 = fopen (outputfilename, "ab");
292#endif
293 // Get the I/P and O/P buffer requirements
294 ioctl_msg.in = NULL;
295 ioctl_msg.out = (void*)&m_sInput_buff_property;
296 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
297 {
298 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
299 return false;
300 }
301 ioctl_msg.in = NULL;
302 ioctl_msg.out = (void*)&m_sOutput_buff_property;
303 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
304 {
305 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
306 return false;
307 }
308
309 m_profile_set = false;
310 m_level_set = false;
311 if(venc_set_profile_level(0, 0))
312 {
313 DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
314 __func__);
315 }
316 recon_buffers_count = MAX_RECON_BUFFERS;
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530317 ltrmode.ltr_mode = 0;
318 ltrcount.ltr_count = 0;
319 ltrperiod.ltr_period = 0;
320
Shalaj Jain273b3e02012-06-22 19:08:03 -0700321 return true;
322}
323
324void venc_dev::venc_close()
325{
326 DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
327 if((int)m_nDriver_fd >= 0)
328 {
329 DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
330 (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
331 NULL);
332 DEBUG_PRINT_LOW("\nCalling close()\n");
333 close(m_nDriver_fd);
334 m_nDriver_fd = -1;
335 }
336#ifdef INPUT_BUFFER_LOG
337 fclose (inputBufferFile1);
338#endif
339#ifdef OUTPUT_BUFFER_LOG
340 fclose (outputBufferFile1);
341#endif
342}
343
344bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
345 unsigned long *actual_buff_count,
346 unsigned long *buff_size,
347 unsigned long port)
348{
349 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
350 unsigned long temp_count = 0;
351
352 if(port == 0)
353 {
354 if(*actual_buff_count > m_sInput_buff_property.mincount)
355 {
356 temp_count = m_sInput_buff_property.actualcount;
357 m_sInput_buff_property.actualcount = *actual_buff_count;
358 ioctl_msg.in = (void*)&m_sInput_buff_property;
359 ioctl_msg.out = NULL;
360 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
361 {
362 DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
363 m_sInput_buff_property.actualcount = temp_count;
364 return false;
365 }
366 DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
367 }
368 }
369 else
370 {
371 if(*actual_buff_count > m_sOutput_buff_property.mincount)
372 {
373 temp_count = m_sOutput_buff_property.actualcount;
374 m_sOutput_buff_property.actualcount = *actual_buff_count;
375 ioctl_msg.in = (void*)&m_sOutput_buff_property;
376 ioctl_msg.out = NULL;
377 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
378 {
379 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
380 m_sOutput_buff_property.actualcount = temp_count;
381 return false;
382 }
383 DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
384 }
385 }
386
387 return true;
388
389}
390
391bool venc_dev::venc_loaded_start()
392{
393 struct timespec ts;
394 int status = 0;
395 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0)
396 {
397 DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed");
398 return false;
399 }
400 if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
401 {
402 DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
403 return false;
404 }
405 ts.tv_sec += 1;
406 pthread_mutex_lock(&loaded_start_stop_mlock);
407 DEBUG_PRINT_LOW("%s: wait on start done", __func__);
408 status = pthread_cond_timedwait(&loaded_start_stop_cond,
409 &loaded_start_stop_mlock, &ts);
410 if (status != 0)
411 {
412 DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
413 status, strerror(status));
414 pthread_mutex_unlock(&loaded_start_stop_mlock);
415 return false;
416 }
417 DEBUG_PRINT_LOW("%s: wait over on start done", __func__);
418 pthread_mutex_unlock(&loaded_start_stop_mlock);
419 DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__);
420 return true;
421}
422
423bool venc_dev::venc_loaded_stop()
424{
425 struct timespec ts;
426 int status = 0;
427 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0)
428 {
429 DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed");
430 return false;
431 }
432 if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
433 {
434 DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
435 return false;
436 }
437 ts.tv_sec += 1;
438 pthread_mutex_lock(&loaded_start_stop_mlock);
439 DEBUG_PRINT_LOW("%s: wait on stop done", __func__);
440 status = pthread_cond_timedwait(&loaded_start_stop_cond,
441 &loaded_start_stop_mlock, &ts);
442 if (status != 0)
443 {
444 DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
445 status, strerror(status));
446 pthread_mutex_unlock(&loaded_start_stop_mlock);
447 return false;
448 }
449 DEBUG_PRINT_LOW("%s: wait over on stop done", __func__);
450 pthread_mutex_unlock(&loaded_start_stop_mlock);
451 DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__);
452 return true;
453}
454
455bool venc_dev::venc_loaded_start_done()
456{
457 pthread_mutex_lock(&loaded_start_stop_mlock);
458 DEBUG_PRINT_LOW("%s: signal start done", __func__);
459 pthread_cond_signal(&loaded_start_stop_cond);
460 pthread_mutex_unlock(&loaded_start_stop_mlock);
461 return true;
462}
463
464bool venc_dev::venc_loaded_stop_done()
465{
466 pthread_mutex_lock(&loaded_start_stop_mlock);
467 DEBUG_PRINT_LOW("%s: signal stop done", __func__);
468 pthread_cond_signal(&loaded_start_stop_cond);
469 pthread_mutex_unlock(&loaded_start_stop_mlock);
470 return true;
471}
472
473bool venc_dev::venc_get_seq_hdr(void *buffer,
474 unsigned buffer_size, unsigned *header_len)
475{
476 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
477 int i = 0;
478 DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr");
479 venc_seqheader seq_in, seq_out;
480 seq_in.hdrlen = 0;
481 seq_in.bufsize = buffer_size;
482 seq_in.hdrbufptr = (unsigned char*)buffer;
483 if (seq_in.hdrbufptr == NULL) {
484 DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed");
485 return false;
486 }
487 DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr,
488 seq_in.bufsize, seq_in.hdrlen);
489
490 ioctl_msg.in = (void*)&seq_in;
491 ioctl_msg.out = (void*)&seq_out;
492 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0)
493 {
494 DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed");
495 return false;
496 }
497 if (seq_out.hdrlen == 0) {
498 DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header");
499 DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
500 seq_out.bufsize, seq_out.hdrlen);
501 return false;
502 }
503 *header_len = seq_out.hdrlen;
504 DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
505 seq_out.bufsize, seq_out.hdrlen);
506
507 return true;
508}
509
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530510bool venc_dev::venc_get_capability_ltrcount(unsigned long *min,
511 unsigned long *max, unsigned long *step_size)
512{
513 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
514 venc_range cap_ltr_count;
515 ioctl_msg.in = NULL;
516 ioctl_msg.out = (void*)&cap_ltr_count;
517 if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT,
518 (void*)&ioctl_msg) < 0)
519 {
520 DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed");
521 return false;
522 }
523 else
524 {
525 *min = cap_ltr_count.min;
526 *max = cap_ltr_count.max;
527 *step_size = cap_ltr_count.step_size;
528 DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d",
529 *min, *max, *step_size);
530 }
531 return true;
532}
533
Shalaj Jain273b3e02012-06-22 19:08:03 -0700534bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
535 unsigned long *actual_buff_count,
536 unsigned long *buff_size,
537 unsigned long port)
538{
539 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
540
541 if(port == 0)
542 {
543 ioctl_msg.in = NULL;
544 ioctl_msg.out = (void*)&m_sInput_buff_property;
545 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
546 {
547 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
548 return false;
549 }
550 *min_buff_count = m_sInput_buff_property.mincount;
551 *actual_buff_count = m_sInput_buff_property.actualcount;
552#ifdef USE_ION
553 // For ION memory allocations of the allocated buffer size
554 // must be 4k aligned, hence aligning the input buffer
555 // size to 4k.
556 m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
557 & (~4095);
558#endif
559 *buff_size = m_sInput_buff_property.datasize;
560 }
561 else
562 {
563 ioctl_msg.in = NULL;
564 ioctl_msg.out = (void*)&m_sOutput_buff_property;
565 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
566 {
567 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
568 return false;
569 }
570 *min_buff_count = m_sOutput_buff_property.mincount;
571 *actual_buff_count = m_sOutput_buff_property.actualcount;
572 *buff_size = m_sOutput_buff_property.datasize;
573 }
574
575 return true;
576
577}
578
579bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
580{
581 venc_ioctl_msg ioctl_msg = {NULL,NULL};
582 DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
583 switch(index)
584 {
585 case OMX_IndexParamPortDefinition:
586 {
587 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
588 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530589 DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700590 if(portDefn->nPortIndex == PORT_INDEX_IN)
591 {
592
593 if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0))
594 {
595 return false;
596 }
597
598 if(!venc_set_color_format(portDefn->format.video.eColorFormat))
599 {
600 return false;
601 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700602
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530603 DEBUG_PRINT_LOW("Basic parameter has changed");
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700604 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
605 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
606
607 ioctl_msg.in = (void*)&m_sVenc_cfg;
608 ioctl_msg.out = NULL;
609 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700610 DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
611 return false;
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700612 }
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530613 DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), "
614 "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
615 m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den,
616 m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700617
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530618 DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution");
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700619 ioctl_msg.in = NULL;
620 ioctl_msg.out = (void*)&m_sInput_buff_property;
621 if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700622 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
623 return false;
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700624 }
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530625 DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: "
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700626 "datasize = %u, maxcount = %u, actualcnt = %u, "
627 "mincount = %u", m_sInput_buff_property.datasize,
628 m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
629 m_sInput_buff_property.mincount);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700630
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700631 ioctl_msg.in = NULL;
632 ioctl_msg.out = (void*)&m_sOutput_buff_property;
633 if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700634 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
635 return false;
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700636 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700637
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530638 DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: "
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700639 "datasize = %u, maxcount = %u, actualcnt = %u, "
640 "mincount = %u", m_sOutput_buff_property.datasize,
641 m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
642 m_sOutput_buff_property.mincount);
643 ioctl_msg.in = (void*)&m_sOutput_buff_property;
644 ioctl_msg.out = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700645
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700646 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700647 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
648 return false;
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700649 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700650
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700651 if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
652 (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700653 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
654 ioctl_msg.in = (void*)&m_sInput_buff_property;
655 ioctl_msg.out = NULL;
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700656 if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700657 DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
658 return false;
659 }
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700660 }
661 if(m_sInput_buff_property.datasize != portDefn->nBufferSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700662 DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
663 "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
664 m_sInput_buff_property.datasize);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700665 }
Haynes Mathew Georgecaa7c2e2012-07-26 15:04:52 -0700666 m_level_set = false;
667 if(venc_set_profile_level(0, 0)) {
Maheshwar Ajja1c976422012-10-20 16:58:10 +0530668 DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700669 }
670 }
671 else if(portDefn->nPortIndex == PORT_INDEX_OUT)
672 {
673 if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0))
674 {
675 return false;
676 }
677
678 if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
679 &&
680 (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
681 &&
682 (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
683 )
684 {
685 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
686 ioctl_msg.in = (void*)&m_sOutput_buff_property;
687 ioctl_msg.out = NULL;
688 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
689 {
690 DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
691 return false;
692 }
693 }
694 else
695 {
696 DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
697 return false;
698 }
699 }
700 else
701 {
702 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
703 }
704 break;
705 }
706 case OMX_IndexParamVideoPortFormat:
707 {
708 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
709 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
710 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
711
712 if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
713 {
714 if(!venc_set_color_format(portFmt->eColorFormat))
715 {
716 return false;
717 }
718 }
719 else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
720 {
721 if(!venc_set_encode_framerate(portFmt->xFramerate, 0))
722 {
723 return false;
724 }
725 }
726 else
727 {
728 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
729 }
730 break;
731 }
732 case OMX_IndexParamVideoBitrate:
733 {
734 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
735 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
736 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
737
738 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
739 {
740 if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0))
741 {
742 DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
743 return false;
744 }
745 if(!venc_set_ratectrl_cfg(pParam->eControlRate))
746 {
747 DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
748 return false;
749 }
750 }
751 else
752 {
753 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
754 }
755 break;
756 }
757 case OMX_IndexParamVideoMpeg4:
758 {
759 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
760 OMX_U32 bFrames = 0;
761
762 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
763 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
764 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
765 {
766 if(!venc_set_voptiming_cfg(pParam->nTimeIncRes))
767 {
768 DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
769 return false;
770 }
771 m_profile_set = false;
772 m_level_set = false;
773 if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
774 {
775 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
776 return false;
777 }
778#ifdef MAX_RES_1080P
779 else {
780 if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
781 {
782 if(pParam->nBFrames)
783 {
784 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
785 bFrames = 1;
786 }
787 }
788 else
789 {
790 if(pParam->nBFrames)
791 {
792 DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
793 bFrames = 0;
794 }
795 }
796 }
797#endif
798 if(!venc_set_intra_period (pParam->nPFrames,bFrames))
799 {
800 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
801 return false;
802 }
803 if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing))
804 {
805 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
806 return false;
807 }
808 }
809 else
810 {
811 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
812 }
813 break;
814 }
815 case OMX_IndexParamVideoH263:
816 {
817 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
818 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
819 OMX_U32 bFrames = 0;
820 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
821 {
822 m_profile_set = false;
823 m_level_set = false;
824 if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
825 {
826 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
827 return false;
828 }
829 if (pParam->nBFrames)
830 DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");
831
832 if(venc_set_intra_period (pParam->nPFrames, bFrames) == false)
833 {
834 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
835 return false;
836 }
837 }
838 else
839 {
840 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
841 }
842 break;
843 }
844 case OMX_IndexParamVideoAvc:
845 {
846 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
847 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
848 OMX_U32 bFrames = 0;
849
850 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
851 {
852 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
853 pParam->eProfile,pParam->eLevel);
854
855 m_profile_set = false;
856 m_level_set = false;
857
858 if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
859 {
860 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
861 pParam->eProfile, pParam->eLevel);
862 return false;
863 }
864#ifdef MAX_RES_1080P
865 else {
866 if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline)
867 {
868 if(pParam->nBFrames)
869 {
870 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
871 bFrames = 1;
872 }
873 }
874 else
875 {
876 if(pParam->nBFrames)
877 {
878 DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
879 bFrames = 0;
880 }
881 }
882 }
883#endif
884 if(!venc_set_intra_period (pParam->nPFrames, bFrames))
885 {
886 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
887 return false;
888 }
889 if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc))
890 {
891 DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
892 return false;
893 }
894 if(!venc_set_inloop_filter (pParam->eLoopFilterMode))
895 {
896 DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
897 return false;
898 }
899 if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing))
900 {
901 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
902 return false;
903 }
904 }
905 else
906 {
907 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
908 }
909 //TBD, lot of other variables to be updated, yet to decide
910 break;
911 }
912 case OMX_IndexParamVideoIntraRefresh:
913 {
914 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
915 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
916 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
917 if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
918 {
919 if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false)
920 {
921 DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
922 return false;
923 }
924 }
925 else
926 {
927 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
928 }
929 break;
930 }
931 case OMX_IndexParamVideoErrorCorrection:
932 {
933 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
934 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
935 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
936 if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
937 {
938 if(venc_set_error_resilience(error_resilience) == false)
939 {
940 DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
941 return false;
942 }
943 }
944 else
945 {
946 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
947 }
948 break;
949 }
950 case OMX_IndexParamVideoProfileLevelCurrent:
951 {
952 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
953 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
954 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
955 if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
956 {
957 m_profile_set = false;
958 m_level_set = false;
959 if(!venc_set_profile_level (profile_level->eProfile,
960 profile_level->eLevel))
961 {
962 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
963 return false;
964 }
965 }
966 else
967 {
968 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
969 }
970 break;
971 }
972 case OMX_IndexParamVideoQuantization:
973 {
974 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
975 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
976 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
977 if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
978 {
979 if(venc_set_session_qp (session_qp->nQpI,
980 session_qp->nQpP) == false)
981 {
982 DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
983 return false;
984 }
985 }
986 else
987 {
988 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
989 }
990 break;
991 }
Rajeshwar Kurapatyd60e2592012-10-08 15:59:09 +0530992
993 case OMX_QcomIndexParamVideoQPRange:
994 {
995 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange\n");
996 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range =
997 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
998 if(qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
999 {
1000 if(venc_set_qp_range (qp_range->minQP,
1001 qp_range->maxQP) == false)
1002 {
1003 DEBUG_PRINT_ERROR("\nERROR: Setting QP Range failed");
1004 return false;
1005 }
1006 }
1007 else
1008 {
1009 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1010 }
1011 break;
1012 }
1013
Shalaj Jain273b3e02012-06-22 19:08:03 -07001014 case OMX_ExtraDataVideoEncoderSliceInfo:
1015 {
1016 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1017 OMX_U32 extra_data = *(OMX_U32 *)paramData;
1018 if(venc_set_extradata(extra_data) == false)
1019 {
1020 DEBUG_PRINT_ERROR("ERROR: Setting "
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301021 "OMX_ExtraDataVideoEncoderSliceInfo failed");
1022 return false;
1023 }
1024 break;
1025 }
1026 case OMX_ExtraDataVideoLTRInfo:
1027 {
1028 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo");
1029 OMX_U32 extra_data = *(OMX_U32 *)paramData;
1030 if(venc_set_extradata(extra_data) == false)
1031 {
1032 DEBUG_PRINT_ERROR("ERROR: Setting "
1033 "OMX_ExtraDataVideoLTRInfo failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001034 return false;
1035 }
1036 break;
1037 }
1038 case OMX_QcomIndexEnableSliceDeliveryMode:
1039 {
1040 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1041 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1042 if(pParam->nPortIndex == PORT_INDEX_OUT)
1043 {
1044 if(venc_set_slice_delivery_mode(pParam->bEnable) == false)
1045 {
1046 DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1047 return OMX_ErrorUnsupportedSetting;
1048 }
1049 }
1050 else
1051 {
1052 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1053 "called on wrong port(%d)", pParam->nPortIndex);
1054 return OMX_ErrorBadPortIndex;
1055 }
1056 break;
1057 }
Shobhit Pandeyc09733d2012-11-27 12:28:44 +05301058 case OMX_QcomIndexEnableH263PlusPType:
1059 {
1060 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1061 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1062 DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
1063 if(pParam->nPortIndex == PORT_INDEX_OUT)
1064 {
1065 if(venc_set_plusptype(pParam->bEnable) == false)
1066 {
1067 DEBUG_PRINT_ERROR("Setting PlusPType failed for H263");
1068 return OMX_ErrorUnsupportedSetting;
1069 }
1070 }
1071 else
1072 {
1073 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType "
1074 "called on wrong port(%d)", pParam->nPortIndex);
1075 return OMX_ErrorBadPortIndex;
1076 }
1077 break;
1078 }
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301079 case QOMX_IndexParamVideoLTRMode:
1080 {
1081 QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam =
1082 (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData;
1083 if(pParam->nPortIndex == PORT_INDEX_OUT)
1084 {
1085 if(!venc_set_ltrmode(pParam->eLTRMode))
1086 {
1087 DEBUG_PRINT_ERROR("Setting ltr mode failed");
1088 return OMX_ErrorUnsupportedSetting;
1089 }
1090 }
1091 else
1092 {
1093 DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode "
1094 "called on wrong port(%d)", pParam->nPortIndex);
1095 return OMX_ErrorBadPortIndex;
1096 }
1097 break;
1098 }
1099 case QOMX_IndexParamVideoLTRCount:
1100 {
1101 QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1102 (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1103 if(pParam->nPortIndex == PORT_INDEX_OUT)
1104 {
1105 if(!venc_set_ltrcount(pParam->nCount))
1106 {
1107 DEBUG_PRINT_ERROR("Setting ltr count failed");
1108 return OMX_ErrorUnsupportedSetting;
1109 }
1110 }
1111 else
1112 {
1113 DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount "
1114 "called on wrong port(%d)", pParam->nPortIndex);
1115 return OMX_ErrorBadPortIndex;
1116 }
1117 break;
1118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001119 case OMX_IndexParamVideoSliceFMO:
1120 default:
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301121 DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001122 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001123 }
1124
1125 return true;
1126}
1127
1128bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1129{
1130 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1131 DEBUG_PRINT_LOW("\n Inside venc_set_config");
1132
1133 switch(index)
1134 {
1135 case OMX_IndexConfigVideoBitrate:
1136 {
1137 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1138 configData;
1139 if(m_max_allowed_bitrate_check &&
1140 !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate))
1141 {
1142 DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed");
1143 return false;
1144 }
1145 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
1146 if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1147 {
1148 if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false)
1149 {
1150 DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
1151 return false;
1152 }
1153 }
1154 else
1155 {
1156 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1157 }
1158 break;
1159 }
1160 case OMX_IndexConfigVideoFramerate:
1161 {
1162 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1163 configData;
1164 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
1165 if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1166 {
1167 if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false)
1168 {
1169 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
1170 return false;
1171 }
1172 }
1173 else
1174 {
1175 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1176 }
1177 break;
1178 }
1179 case QOMX_IndexConfigVideoIntraperiod:
1180 {
1181 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
1182 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1183 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1184 if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1185 {
1186 if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false)
1187 {
1188 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
1189 return false;
1190 }
1191 }
1192 break;
1193 }
1194 case OMX_IndexConfigVideoIntraVOPRefresh:
1195 {
1196 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1197 configData;
1198 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1199 if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1200 {
1201 if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
1202 {
1203 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
1204 return false;
1205 }
1206 }
1207 else
1208 {
1209 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1210 }
1211 break;
1212 }
1213 case OMX_IndexConfigCommonRotate:
1214 {
1215 OMX_CONFIG_ROTATIONTYPE *config_rotation =
1216 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1217 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1218 OMX_U32 nFrameWidth;
1219
1220 DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
1221 nFrameWidth = m_sVenc_cfg.input_width;
1222 m_sVenc_cfg.input_width = m_sVenc_cfg.input_height;
1223 m_sVenc_cfg.input_height = nFrameWidth;
1224 ioctl_msg.in = (void*)&m_sVenc_cfg;
1225 ioctl_msg.out = NULL;
1226 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
1227 DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
1228 return false;
1229 }
1230 break;
1231 }
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301232 case QOMX_IndexConfigVideoLTRPeriod:
1233 {
1234 QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam =
1235 (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData;
1236 if(pParam->nPortIndex == PORT_INDEX_OUT)
1237 {
1238 if(!venc_set_ltrperiod(pParam->nFrames))
1239 {
1240 DEBUG_PRINT_ERROR("Setting ltr period failed");
1241 return OMX_ErrorUnsupportedSetting;
1242 }
1243 }
1244 else
1245 {
1246 DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod "
1247 "called on wrong port(%d)", pParam->nPortIndex);
1248 return OMX_ErrorBadPortIndex;
1249 }
1250 break;
1251 }
1252 case QOMX_IndexConfigVideoLTRUse:
1253 {
1254 QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam =
1255 (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
1256 if(pParam->nPortIndex == PORT_INDEX_OUT)
1257 {
1258 if(!venc_set_ltruse(pParam->nID, pParam->nFrames))
1259 {
1260 DEBUG_PRINT_ERROR("Setting ltr use failed");
1261 return OMX_ErrorUnsupportedSetting;
1262 }
1263 }
1264 else
1265 {
1266 DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse "
1267 "called on wrong port(%d)", pParam->nPortIndex);
1268 return OMX_ErrorBadPortIndex;
1269 }
1270 break;
1271 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001272 default:
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301273 DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001274 break;
1275 }
1276
1277 return true;
1278}
1279
1280unsigned venc_dev::venc_stop( void)
1281{
1282#ifdef MAX_RES_1080P
1283 pmem_free();
1284#endif
1285 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
1286}
1287
1288unsigned venc_dev::venc_pause(void)
1289{
1290 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
1291}
1292
1293unsigned venc_dev::venc_resume(void)
1294{
1295 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
1296}
1297
1298unsigned venc_dev::venc_start_done(void)
1299{
1300 return 0;
1301}
1302
Praneeth Paladugu4c115442012-08-06 16:11:06 -07001303unsigned venc_dev::venc_set_message_thread_id(pthread_t)
1304{
1305 return 0;
1306}
1307
Shalaj Jain273b3e02012-06-22 19:08:03 -07001308unsigned venc_dev::venc_start(void)
1309{
1310 DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
1311 __func__);
1312 if (!venc_set_profile_level(0, 0))
1313 {
1314 DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
1315 __func__);
1316 }
1317 else
1318 {
1319 DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
1320 __func__, codec_profile.profile, profile_level.level);
1321 }
1322
1323 if(m_max_allowed_bitrate_check &&
1324 !venc_max_allowed_bitrate_check(bitrate.target_bitrate))
1325 {
1326 DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed");
1327 return -1;
1328 }
1329
1330 venc_config_print();
1331
1332#ifdef MAX_RES_1080P
1333 if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) ||
1334 (codec_profile.profile == VEN_PROFILE_H264_BASELINE) ||
1335 (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
1336 recon_buffers_count = MAX_RECON_BUFFERS - 2;
1337 else
1338 recon_buffers_count = MAX_RECON_BUFFERS;
1339
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301340 if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto)
1341 {
1342 recon_buffers_count = MAX_RECON_BUFFERS;
1343 DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers "
1344 "count to %d", recon_buffers_count);
1345 }
1346
Shalaj Jain273b3e02012-06-22 19:08:03 -07001347 if (!venc_allocate_recon_buffers())
1348 return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
1349 else
1350 {
1351 DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n");
1352 return -1;
1353 }
1354#else
1355 return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
1356#endif
1357}
1358
1359#ifdef MAX_RES_1080P
1360OMX_U32 venc_dev::venc_allocate_recon_buffers()
1361{
1362 OMX_U32 yuv_size;
1363 struct venc_ioctl_msg ioctl_msg;
1364 struct venc_recon_buff_size recon_buff_size;
1365
1366 recon_buff_size.width = ((m_sVenc_cfg.input_width + 15) / 16) * 16;
1367 recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16;
1368
1369 DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width,
1370 m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height);
1371
1372 ioctl_msg.in = NULL;
1373 ioctl_msg.out = (void*)&recon_buff_size;
1374
1375 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0)
1376 {
1377 DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" ,
1378 recon_buff_size.width, recon_buff_size.height);
1379 return OMX_ErrorInsufficientResources;
1380 }
1381
1382 DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n",
1383 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width,
1384 recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment,
1385 recon_buffers_count);
1386
1387 for(int i = 0; i < recon_buffers_count; i++)
1388 {
1389 if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i))
1390 {
1391 DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n");
1392 return -1;
1393 }
1394 }
1395 return 0;
1396}
1397OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
1398{
1399 OMX_U32 pmem_fd = -1;
1400 OMX_U32 width, height;
1401 void *buf_addr = NULL;
1402 struct venc_ioctl_msg ioctl_msg;
1403 struct venc_recon_addr recon_addr;
1404 int rc = 0;
1405
1406#ifdef USE_ION
1407 recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY);
1408 if(recon_buff[count].ion_device_fd < 0)
1409 {
1410 DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
1411 return -1;
1412 }
1413
1414 recon_buff[count].alloc_data.len = size;
Maheshwar Ajjab0e74262012-07-27 19:09:12 +05301415#ifdef MAX_RES_720P
Arun Menon737de532012-09-14 14:48:18 -07001416 recon_buff[count].alloc_data.heap_mask = ION_HEAP(MEM_HEAP_ID);
Maheshwar Ajjab0e74262012-07-27 19:09:12 +05301417#else
Arun Menon737de532012-09-14 14:48:18 -07001418 recon_buff[count].alloc_data.heap_mask = (ION_HEAP(MEM_HEAP_ID) |
Shalaj Jain273b3e02012-06-22 19:08:03 -07001419 ION_HEAP(ION_IOMMU_HEAP_ID));
Maheshwar Ajjab0e74262012-07-27 19:09:12 +05301420#endif
Arun Menon737de532012-09-14 14:48:18 -07001421 recon_buff[count].alloc_data.flags = ION_FLAG_CACHED;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001422 recon_buff[count].alloc_data.align = clip2(alignment);
1423 if (recon_buff[count].alloc_data.align != 8192)
1424 recon_buff[count].alloc_data.align = 8192;
1425
1426 rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
1427 if(rc || !recon_buff[count].alloc_data.handle) {
1428 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
1429 recon_buff[count].alloc_data.handle=NULL;
1430 return -1;
1431 }
1432
1433 recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
1434 rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
1435 if(rc) {
1436 DEBUG_PRINT_ERROR("\n ION MAP failed ");
1437 recon_buff[count].ion_alloc_fd.fd =-1;
1438 recon_buff[count].ion_alloc_fd.fd =-1;
1439 return -1;
1440 }
1441 pmem_fd = recon_buff[count].ion_alloc_fd.fd;
1442#else
1443 struct pmem_allocation allocation;
1444 pmem_fd = open(MEM_DEVICE, O_RDWR);
1445
1446 if ((int)(pmem_fd) < 0)
1447 {
1448 DEBUG_PRINT_ERROR("\n Failed to get an pmem handle");
1449 return -1;
1450 }
1451
1452 allocation.size = size;
1453 allocation.align = clip2(alignment);
1454
1455 if (allocation.align != 8192)
1456 allocation.align = 8192;
1457
1458 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
1459 {
1460 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
1461 allocation.align, allocation.size);
1462 return -1;
1463 }
1464#endif
1465 buf_addr = mmap(NULL, size,
1466 PROT_READ | PROT_WRITE,
1467 MAP_SHARED, pmem_fd, 0);
1468
1469 if (buf_addr == (void*) MAP_FAILED)
1470 {
1471 close(pmem_fd);
1472 pmem_fd = -1;
1473 DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
1474#ifdef USE_ION
1475 if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
1476 &recon_buff[count].alloc_data.handle)) {
Rajeshwar Kurapaty21459eb2012-08-16 17:14:54 -07001477 DEBUG_PRINT_LOW("ion recon buffer free failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001478 }
1479 recon_buff[count].alloc_data.handle = NULL;
1480 recon_buff[count].ion_alloc_fd.fd =-1;
1481 close(recon_buff[count].ion_device_fd);
1482 recon_buff[count].ion_device_fd =-1;
1483#endif
1484 return -1;
1485 }
1486
1487 DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size);
1488
1489 recon_addr.buffer_size = size;
1490 recon_addr.pmem_fd = pmem_fd;
1491 recon_addr.offset = 0;
1492 recon_addr.pbuffer = (unsigned char *)buf_addr;
1493
1494 ioctl_msg.in = (void*)&recon_addr;
1495 ioctl_msg.out = NULL;
1496
1497 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0)
1498 {
1499 DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n");
1500 return -1;
1501 }
1502
1503 recon_buff[count].virtual_address = (unsigned char *) buf_addr;
1504 recon_buff[count].size = size;
1505 recon_buff[count].offset = 0;
1506 recon_buff[count].pmem_fd = pmem_fd;
1507
1508 DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address,
1509 recon_buff[count].pmem_fd, recon_buff[count].size, count);
1510 return 0;
1511}
1512
1513OMX_U32 venc_dev::pmem_free()
1514{
1515 int cnt = 0;
1516 struct venc_ioctl_msg ioctl_msg;
1517 struct venc_recon_addr recon_addr;
1518 for (cnt = 0; cnt < recon_buffers_count; cnt++)
1519 {
1520 if(recon_buff[cnt].pmem_fd)
1521 {
1522 recon_addr.pbuffer = recon_buff[cnt].virtual_address;
1523 recon_addr.offset = recon_buff[cnt].offset;
1524 recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
1525 recon_addr.buffer_size = recon_buff[cnt].size;
1526 ioctl_msg.in = (void*)&recon_addr;
1527 ioctl_msg.out = NULL;
1528 if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0)
1529 DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
1530 munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
1531 close(recon_buff[cnt].pmem_fd);
1532#ifdef USE_ION
1533 if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
1534 &recon_buff[cnt].alloc_data.handle)) {
Rajeshwar Kurapaty21459eb2012-08-16 17:14:54 -07001535 DEBUG_PRINT_LOW("ion recon buffer free failed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001536 }
1537 recon_buff[cnt].alloc_data.handle = NULL;
1538 recon_buff[cnt].ion_alloc_fd.fd =-1;
1539 close(recon_buff[cnt].ion_device_fd);
1540 recon_buff[cnt].ion_device_fd =-1;
1541#endif
1542 DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size);
1543 recon_buff[cnt].pmem_fd = -1;
1544 recon_buff[cnt].virtual_address = NULL;
1545 recon_buff[cnt].offset = 0;
1546 recon_buff[cnt].alignment = 0;
1547 recon_buff[cnt].size = 0;
1548 }
1549 }
1550 return 0;
1551}
1552#endif
1553
1554void venc_dev::venc_config_print()
1555{
1556
1557 DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d",
1558 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
1559
1560 DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
1561 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
1562 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
1563
1564 DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
1565 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
1566
1567 DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
1568 session_qp.iframeqp, session_qp.pframqp);
1569
Rajeshwar Kurapatyd60e2592012-10-08 15:59:09 +05301570 DEBUG_PRINT_HIGH("\nENC_CONFIG: minQP: %d, maxQP: %d",
1571 qp_range.minqp, qp_range.maxqp);
1572
Shalaj Jain273b3e02012-06-22 19:08:03 -07001573 DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
1574 voptimecfg.voptime_resolution, multislice.mslice_mode,
1575 multislice.mslice_size);
1576
1577 DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d",
1578 entropy.longentropysel, entropy.cabacmodel);
1579
1580 DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n",
1581 dbkfilter.db_mode, dbkfilter.slicealpha_offset,
1582 dbkfilter.slicebeta_offset);
1583
1584 DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n",
1585 intra_refresh.mbcount, hec.header_extension);
1586}
1587
1588unsigned venc_dev::venc_flush( unsigned port)
1589{
1590 struct venc_ioctl_msg ioctl_msg;
1591 struct venc_bufferflush buffer_index;
1592
1593 if(port == PORT_INDEX_IN)
1594 {
1595 DEBUG_PRINT_HIGH("Calling Input Flush");
1596 buffer_index.flush_mode = VEN_FLUSH_INPUT;
1597 ioctl_msg.in = (void*)&buffer_index;
1598 ioctl_msg.out = NULL;
1599
1600 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
1601 }
1602 else if(port == PORT_INDEX_OUT)
1603 {
1604 DEBUG_PRINT_HIGH("Calling Output Flush");
1605 buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
1606 ioctl_msg.in = (void*)&buffer_index;
1607 ioctl_msg.out = NULL;
1608 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
1609 }
1610 else
1611 {
1612 return -1;
1613 }
1614}
1615
1616//allocating I/P memory from pmem and register with the device
1617
1618
1619bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned)
1620{
1621 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1622 struct pmem *pmem_tmp;
1623 struct venc_bufferpayload dev_buffer = {0};
Deepak Verma3040f6f2012-08-30 18:35:49 +05301624 struct venc_allocatorproperty buff_alloc_property = {0};
Shalaj Jain273b3e02012-06-22 19:08:03 -07001625
1626 pmem_tmp = (struct pmem *)buf_addr;
1627
1628 DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
1629
1630 if(port == PORT_INDEX_IN)
1631 {
1632 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1633 dev_buffer.fd = pmem_tmp->fd;
1634 dev_buffer.maped_size = pmem_tmp->size;
1635 dev_buffer.sz = pmem_tmp->size;
1636 dev_buffer.offset = pmem_tmp->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637
Arun Menon7e2a49e2012-06-08 15:17:37 -07001638 if((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0))
1639 {
1640 unsigned long ht = m_sVenc_cfg.input_height;
1641 unsigned long wd = m_sVenc_cfg.input_width;
1642 unsigned int luma_size, luma_size_2k;
1643
1644 ht = (ht + 15) & ~15;
1645 wd = (wd + 15) & ~15;
1646
1647 luma_size = ht * wd;
1648 luma_size_2k = (luma_size + 2047) & ~2047;
1649
Deepak Verma3040f6f2012-08-30 18:35:49 +05301650 dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047);
1651#ifdef USE_ION
1652 ioctl_msg.in = NULL;
1653 ioctl_msg.out = (void*)&buff_alloc_property;
1654 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
1655 {
1656 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:get input buffer failed ");
1657 return false;
1658 }
1659 if(buff_alloc_property.alignment < 4096)
1660 {
1661 dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095);
1662 }
1663 else
1664 {
1665 dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) &
1666 ~(buff_alloc_property.alignment - 1));
1667 }
1668#endif
Arun Menon7e2a49e2012-06-08 15:17:37 -07001669 dev_buffer.maped_size = dev_buffer.sz;
1670 }
1671
Deepak Verma3040f6f2012-08-30 18:35:49 +05301672 ioctl_msg.in = (void*)&dev_buffer;
1673 ioctl_msg.out = NULL;
1674
Shalaj Jain273b3e02012-06-22 19:08:03 -07001675 DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1676 dev_buffer.pbuffer, \
1677 dev_buffer.fd, \
1678 dev_buffer.offset, \
1679 dev_buffer.maped_size);
1680
1681 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0)
1682 {
1683 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
1684 return false;
1685 }
1686 }
1687 else if(port == PORT_INDEX_OUT)
1688 {
1689 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1690 dev_buffer.fd = pmem_tmp->fd;
1691 dev_buffer.sz = pmem_tmp->size;
1692 dev_buffer.maped_size = pmem_tmp->size;
1693 dev_buffer.offset = pmem_tmp->offset;
1694 ioctl_msg.in = (void*)&dev_buffer;
1695 ioctl_msg.out = NULL;
1696
1697 DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1698 dev_buffer.pbuffer, \
1699 dev_buffer.fd, \
1700 dev_buffer.offset, \
1701 dev_buffer.maped_size);
1702
1703 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0)
1704 {
1705 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
1706 return false;
1707 }
1708 }
1709 else
1710 {
1711 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
1712 return false;
1713 }
1714
1715 return true;
1716}
1717
1718bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
1719{
1720 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1721 struct pmem *pmem_tmp;
1722 struct venc_bufferpayload dev_buffer = {0};
1723
1724 pmem_tmp = (struct pmem *)buf_addr;
1725
1726 DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
1727
1728 if(port == PORT_INDEX_IN)
1729 {
1730 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1731 dev_buffer.fd = pmem_tmp->fd;
1732 dev_buffer.maped_size = pmem_tmp->size;
1733 dev_buffer.sz = pmem_tmp->size;
1734 dev_buffer.offset = pmem_tmp->offset;
1735 ioctl_msg.in = (void*)&dev_buffer;
1736 ioctl_msg.out = NULL;
1737
1738 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1739 dev_buffer.pbuffer, \
1740 dev_buffer.fd, \
1741 dev_buffer.offset, \
1742 dev_buffer.maped_size);
1743
1744 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0)
1745 {
1746 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
1747 return false;
1748 }
1749 }
1750 else if(port == PORT_INDEX_OUT)
1751 {
1752 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
1753 dev_buffer.fd = pmem_tmp->fd;
1754 dev_buffer.sz = pmem_tmp->size;
1755 dev_buffer.maped_size = pmem_tmp->size;
1756 dev_buffer.offset = pmem_tmp->offset;
1757 ioctl_msg.in = (void*)&dev_buffer;
1758 ioctl_msg.out = NULL;
1759
1760 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
1761 dev_buffer.pbuffer, \
1762 dev_buffer.fd, \
1763 dev_buffer.offset, \
1764 dev_buffer.maped_size);
1765
1766 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0)
1767 {
1768 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
1769 return false;
1770 }
1771 }
1772 else
1773 {
1774 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
1775 return false;
1776 }
1777
1778 return true;
1779}
1780
1781bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
1782{
1783 struct venc_buffer frameinfo;
1784 struct pmem *temp_buffer;
1785 struct venc_ioctl_msg ioctl_msg;
1786 struct OMX_BUFFERHEADERTYPE *bufhdr;
1787
1788 if(buffer == NULL)
1789 {
1790 DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
1791 return false;
1792 }
1793 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1794
1795 DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
1796
1797 if(pmem_data_buf)
1798 {
1799 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
1800 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
1801 }
1802 else
1803 {
1804 DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1805 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
1806 }
1807
1808 frameinfo.clientdata = (void *) buffer;
1809 frameinfo.sz = bufhdr->nFilledLen;
1810 frameinfo.len = bufhdr->nFilledLen;
1811 frameinfo.flags = bufhdr->nFlags;
1812 frameinfo.offset = bufhdr->nOffset;
1813 frameinfo.timestamp = bufhdr->nTimeStamp;
1814 DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp);
1815 ioctl_msg.in = &frameinfo;
1816 ioctl_msg.out = NULL;
1817
1818 DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
1819 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
1820 if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
1821 {
1822 /*Generate an async error and move to invalid state*/
1823 return false;
1824 }
1825#ifdef INPUT_BUFFER_LOG
1826#ifdef MAX_RES_1080P
1827
1828 int y_size = 0;
1829 int c_offset = 0;
1830 unsigned char *buf_addr = NULL;
1831
1832 y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
1833 //chroma offset is y_size aligned to the 2k boundary
1834 c_offset= (y_size + 2047) & (~(2047));
1835
1836 if(pmem_data_buf)
1837 {
1838 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
1839 buf_addr = (OMX_U8 *)pmem_data_buf;
1840 }
1841 else
1842 {
1843 DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1844 buf_addr = (unsigned char *)mmap(NULL,
1845 ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2],
1846 PROT_READ|PROT_WRITE, MAP_SHARED,
1847 ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0);
1848 }
1849
1850 if(inputBufferFile1)
1851 {
1852 fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1);
1853 fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1);
1854 }
1855
1856 munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]);
1857#else
1858 if(inputBufferFile1)
1859 {
1860 fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1);
1861 }
1862#endif
1863
1864#endif
1865 return true;
1866}
1867bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
1868{
1869 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
1870 struct pmem *temp_buffer = NULL;
1871 struct venc_buffer frameinfo;
1872 struct OMX_BUFFERHEADERTYPE *bufhdr;
1873
1874 if(buffer == NULL)
1875 {
1876 return false;
1877 }
1878 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
1879
1880 if(pmem_data_buf)
1881 {
1882 DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
1883 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
1884 }
1885 else
1886 {
1887 DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
1888 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
1889 }
1890
1891 frameinfo.clientdata = buffer;
1892 frameinfo.sz = bufhdr->nAllocLen;
1893 frameinfo.flags = bufhdr->nFlags;
1894 frameinfo.offset = bufhdr->nOffset;
1895
1896 ioctl_msg.in = &frameinfo;
1897 ioctl_msg.out = NULL;
1898 DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
1899 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
1900 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
1901 {
1902 DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
1903 return false;
1904 }
1905
1906 return true;
1907}
1908
1909bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable)
1910{
1911 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1912 DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable);
1913 if(multislice.mslice_mode == VEN_MSLICE_CNT_MB)
1914 {
1915 if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0)
1916 {
1917 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
1918 return false;
1919 }
1920 }
1921 else
1922 {
1923 DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set "
1924 "slice delivery mode to the driver.", multislice.mslice_mode);
1925 }
1926 return true;
1927}
1928
Shobhit Pandeyc09733d2012-11-27 12:28:44 +05301929bool venc_dev::venc_set_plusptype(OMX_BOOL enable)
1930{
1931 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1932 struct venc_plusptype plusptype = {0};
1933 DEBUG_PRINT_LOW("Set plusptype: %d", enable);
1934 plusptype.plusptype_enable = enable;
1935 ioctl_msg.in = (void*)&plusptype;
1936 ioctl_msg.out = NULL;
1937 if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0)
1938 {
1939 DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed");
1940 return false;
1941 }
1942 return true;
1943}
1944
Maheshwar Ajja1c976422012-10-20 16:58:10 +05301945bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode)
1946{
1947 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1948 venc_ltrmode ltr_mode;
1949 ltr_mode.ltr_mode = (unsigned long)mode;
1950 DEBUG_PRINT_HIGH("Set ltr mode: %d", mode);
1951 ioctl_msg.in = (void*)&ltr_mode;
1952 ioctl_msg.out = NULL;
1953 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0)
1954 {
1955 DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed");
1956 return false;
1957 }
1958 ltrmode.ltr_mode = (unsigned long)mode;
1959 return true;
1960}
1961
1962bool venc_dev::venc_set_ltrcount(OMX_U32 count)
1963{
1964 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1965 venc_ltrcount ltr_count;
1966 ltr_count.ltr_count = (unsigned long)count;
1967 DEBUG_PRINT_HIGH("Set ltr count: %d", count);
1968 ioctl_msg.in = (void*)&ltr_count;
1969 ioctl_msg.out = NULL;
1970 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0)
1971 {
1972 DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed");
1973 return false;
1974 }
1975 ltrcount.ltr_count = (unsigned long)count;
1976 return true;
1977}
1978
1979bool venc_dev::venc_set_ltrperiod(OMX_U32 period)
1980{
1981 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1982 venc_ltrperiod ltr_period;
1983 ltr_period.ltr_period = (unsigned long)period;
1984 DEBUG_PRINT_HIGH("Set ltr period: %d", period);
1985 ioctl_msg.in = (void*)&ltr_period;
1986 ioctl_msg.out = NULL;
1987 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0)
1988 {
1989 DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed");
1990 return false;
1991 }
1992 ltrperiod.ltr_period = (unsigned long)period;
1993 return true;
1994}
1995
1996bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames)
1997{
1998 venc_ioctl_msg ioctl_msg = {NULL,NULL};
1999 venc_ltruse ltr_use;
2000 ltr_use.ltr_id = (unsigned long)id;
2001 ltr_use.ltr_frames = (unsigned long)frames;
2002 DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames);
2003 ioctl_msg.in = (void*)&ltr_use;
2004 ioctl_msg.out = NULL;
2005 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0)
2006 {
2007 DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed");
2008 return false;
2009 }
2010 return true;
2011}
2012
Shalaj Jain273b3e02012-06-22 19:08:03 -07002013bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
2014{
2015 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2016 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data);
2017 ioctl_msg.in = (void*)&extra_data;
2018 ioctl_msg.out = NULL;
2019 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0)
2020 {
2021 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
2022 return false;
2023 }
2024
2025 return true;
2026}
2027
2028bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
2029{
2030 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2031 struct venc_sessionqp qp = {0, 0};
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302032 DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002033 p_frame_qp);
2034
2035 qp.iframeqp = i_frame_qp;
2036 qp.pframqp = p_frame_qp;
2037
2038 ioctl_msg.in = (void*)&qp;
2039 ioctl_msg.out = NULL;
2040 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0)
2041 {
2042 DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
2043 return false;
2044 }
2045
2046 session_qp.iframeqp = i_frame_qp;
2047 session_qp.pframqp = p_frame_qp;
2048
2049 return true;
2050}
2051
Rajeshwar Kurapatyd60e2592012-10-08 15:59:09 +05302052bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
2053{
2054 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2055 struct venc_qprange qp = {0, 0};
2056 DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp,
2057 max_qp);
2058
2059 qp.minqp = min_qp;
2060 qp.maxqp = max_qp;
2061
2062 ioctl_msg.in = (void*)&qp;
2063 ioctl_msg.out = NULL;
2064 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0)
2065 {
2066 DEBUG_PRINT_ERROR("\nERROR: Request for setting qp range failed");
2067 return false;
2068 }
2069
2070 qp_range.minqp= min_qp;
2071 qp_range.maxqp= max_qp;
2072
2073 return true;
2074}
2075
Shalaj Jain273b3e02012-06-22 19:08:03 -07002076bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
2077{
2078 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2079 struct venc_profile requested_profile;
2080 struct ven_profilelevel requested_level;
2081 unsigned const int *profile_tbl = NULL;
2082 unsigned long mb_per_frame = 0, mb_per_sec = 0;
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302083 DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002084 eProfile, eLevel);
2085 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
2086 ((m_sVenc_cfg.input_width + 15) >> 4);
2087 if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
2088 {
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302089 DEBUG_PRINT_HIGH("Set profile/level was done already");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002090 return true;
2091 }
2092
2093 if(eProfile && eLevel)
2094 {
2095 /* non-zero values will be set by user, saving the same*/
2096 m_eProfile = eProfile;
2097 m_eLevel = eLevel;
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302098 DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check",
2099 m_eProfile, m_eLevel);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002100 }
2101
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302102 DEBUG_PRINT_LOW("Validating Profile/Level from table");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002103 if(!venc_validate_profile_level(&eProfile, &eLevel))
2104 {
2105 DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
2106 return false;
2107 }
2108
2109 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
2110 {
2111 DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
2112 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
2113 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
2114 if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
2115 {
2116 requested_profile.profile = VEN_PROFILE_MPEG4_SP;
2117 profile_tbl = (unsigned int const *)
2118 (&mpeg4_profile_level_table[MPEG4_SP_START]);
2119 profile_tbl += MPEG4_720P_LEVEL*5;
2120 }
2121 else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
2122 {
2123 requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
2124 profile_tbl = (unsigned int const *)
2125 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
2126 profile_tbl += MPEG4_720P_LEVEL*5;
2127 }
2128 else
2129 {
2130 DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
2131 eProfile);
2132 return false;
2133 }
2134
2135 DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
2136 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
2137 "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
2138 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
2139
2140 if(mb_per_frame >= 3600)
2141 {
2142 if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP)
2143 requested_level.level = VEN_LEVEL_MPEG4_5;
2144 if(requested_profile.profile == VEN_PROFILE_MPEG4_SP)
2145 requested_level.level = VEN_LEVEL_MPEG4_6;
2146 }
2147 else
2148 {
2149 switch(eLevel)
2150 {
2151 case OMX_VIDEO_MPEG4Level0:
2152 requested_level.level = VEN_LEVEL_MPEG4_0;
2153 break;
2154 case OMX_VIDEO_MPEG4Level1:
2155 requested_level.level = VEN_LEVEL_MPEG4_1;
2156 break;
2157 case OMX_VIDEO_MPEG4Level2:
2158 requested_level.level = VEN_LEVEL_MPEG4_2;
2159 break;
2160 case OMX_VIDEO_MPEG4Level3:
2161 requested_level.level = VEN_LEVEL_MPEG4_3;
2162 break;
2163 case OMX_VIDEO_MPEG4Level4a:
2164 requested_level.level = VEN_LEVEL_MPEG4_4;
2165 break;
2166 case OMX_VIDEO_MPEG4Level5:
2167 mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
2168 if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) &&
2169 (mb_per_sec >= profile_tbl[1]))
2170 {
2171 DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
2172 requested_level.level = VEN_LEVEL_MPEG4_6;
2173 }
2174 else
2175 {
2176 DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
2177 requested_level.level = VEN_LEVEL_MPEG4_5;
2178 }
2179 break;
2180 default:
2181 return false;
2182 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
2183 break;
2184 }
2185 }
2186 }
2187 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
2188 {
2189 if(eProfile == OMX_VIDEO_H263ProfileBaseline)
2190 {
2191 requested_profile.profile = VEN_PROFILE_H263_BASELINE;
2192 }
2193 else
2194 {
2195 DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
2196 requested_profile.profile);
2197 return false;
2198 }
2199 //profile level
2200 switch(eLevel)
2201 {
2202 case OMX_VIDEO_H263Level10:
2203 requested_level.level = VEN_LEVEL_H263_10;
2204 break;
2205 case OMX_VIDEO_H263Level20:
2206 requested_level.level = VEN_LEVEL_H263_20;
2207 break;
2208 case OMX_VIDEO_H263Level30:
2209 requested_level.level = VEN_LEVEL_H263_30;
2210 break;
2211 case OMX_VIDEO_H263Level40:
2212 requested_level.level = VEN_LEVEL_H263_40;
2213 break;
2214 case OMX_VIDEO_H263Level45:
2215 requested_level.level = VEN_LEVEL_H263_45;
2216 break;
2217 case OMX_VIDEO_H263Level50:
2218 requested_level.level = VEN_LEVEL_H263_50;
2219 break;
2220 case OMX_VIDEO_H263Level60:
2221 requested_level.level = VEN_LEVEL_H263_60;
2222 break;
2223 case OMX_VIDEO_H263Level70:
2224 requested_level.level = VEN_LEVEL_H263_70;
2225 break;
2226 default:
2227 return false;
2228 break;
2229 }
2230 }
2231 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
2232 {
2233 if(eProfile == OMX_VIDEO_AVCProfileBaseline)
2234 {
2235 requested_profile.profile = VEN_PROFILE_H264_BASELINE;
2236 }
2237 else if(eProfile == OMX_VIDEO_AVCProfileMain)
2238 {
2239 requested_profile.profile = VEN_PROFILE_H264_MAIN;
2240 }
2241 else if(eProfile == OMX_VIDEO_AVCProfileHigh)
2242 {
2243 requested_profile.profile = VEN_PROFILE_H264_HIGH;
2244 }
2245 else
2246 {
2247 DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
2248 requested_profile.profile);
2249 return false;
2250 }
2251 //profile level
2252 switch(eLevel)
2253 {
2254 case OMX_VIDEO_AVCLevel1:
2255 requested_level.level = VEN_LEVEL_H264_1;
2256 break;
2257 case OMX_VIDEO_AVCLevel1b:
2258 requested_level.level = VEN_LEVEL_H264_1b;
2259 break;
2260 case OMX_VIDEO_AVCLevel11:
2261 requested_level.level = VEN_LEVEL_H264_1p1;
2262 break;
2263 case OMX_VIDEO_AVCLevel12:
2264 requested_level.level = VEN_LEVEL_H264_1p2;
2265 break;
2266 case OMX_VIDEO_AVCLevel13:
2267 requested_level.level = VEN_LEVEL_H264_1p3;
2268 break;
2269 case OMX_VIDEO_AVCLevel2:
2270 requested_level.level = VEN_LEVEL_H264_2;
2271 break;
2272 case OMX_VIDEO_AVCLevel21:
2273 requested_level.level = VEN_LEVEL_H264_2p1;
2274 break;
2275 case OMX_VIDEO_AVCLevel22:
2276 requested_level.level = VEN_LEVEL_H264_2p2;
2277 break;
2278 case OMX_VIDEO_AVCLevel3:
2279 requested_level.level = VEN_LEVEL_H264_3;
2280 break;
2281 case OMX_VIDEO_AVCLevel31:
2282 requested_level.level = VEN_LEVEL_H264_3p1;
2283 break;
2284 case OMX_VIDEO_AVCLevel32:
2285 requested_level.level = VEN_LEVEL_H264_3p2;
2286 break;
2287 case OMX_VIDEO_AVCLevel4:
2288 requested_level.level = VEN_LEVEL_H264_4;
2289 break;
2290 default :
2291 DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u",
2292 requested_level.level);
2293 return false;
2294 break;
2295 }
2296 }
2297 if(!m_profile_set)
2298 {
2299 ioctl_msg.in = (void*)&requested_profile;
2300 ioctl_msg.out = NULL;
2301 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0)
2302 {
2303 DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed");
2304 return false;
2305 }
2306 codec_profile.profile = requested_profile.profile;
2307 m_profile_set = true;
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302308 DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002309 }
2310
2311 if(!m_level_set)
2312 {
2313 ioctl_msg.in = (void*)&requested_level;
2314 ioctl_msg.out = NULL;
2315 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0)
2316 {
2317 DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed");
2318 return false;
2319 }
2320 profile_level.level = requested_level.level;
2321 m_level_set = true;
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302322 DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002323 }
2324
2325 return true;
2326}
2327
2328bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
2329{
2330 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2331 struct venc_voptimingcfg vop_timing_cfg;
2332
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302333 DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002334 TimeIncRes);
2335
2336 vop_timing_cfg.voptime_resolution = TimeIncRes;
2337
2338 ioctl_msg.in = (void*)&vop_timing_cfg;
2339 ioctl_msg.out = NULL;
2340 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0)
2341 {
2342 DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed");
2343 return false;
2344 }
2345
2346 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
2347 return true;
2348}
2349
2350bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
2351{
2352 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2353 struct venc_intraperiod intraperiod_cfg;
2354
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302355 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002356 nPFrames);
2357 intraperiod_cfg.num_pframes = nPFrames;
2358 if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) ||
2359 (codec_profile.profile == VEN_PROFILE_H264_MAIN) ||
2360 (codec_profile.profile == VEN_PROFILE_H264_HIGH))
2361 {
2362#ifdef MAX_RES_1080P
2363 if (nBFrames)
2364 {
2365 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
2366 intraperiod_cfg.num_bframes = 1;
2367 }
2368 else
2369 intraperiod_cfg.num_bframes = 0;
2370#else
2371 if(nBFrames)
2372 {
2373 DEBUG_PRINT_ERROR("B frames not supported");
2374 intraperiod_cfg.num_bframes = 0;
2375 }
2376 else
2377 {
2378 DEBUG_PRINT_ERROR("B frames not supported");
2379 intraperiod_cfg.num_bframes = 0;
2380 }
2381#endif
2382 }
2383 else
2384 intraperiod_cfg.num_bframes = 0;
2385
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302386 DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002387 intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes);
2388 ioctl_msg.in = (void*)&intraperiod_cfg;
2389 ioctl_msg.out = NULL;
2390 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0)
2391 {
2392 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
2393 return false;
2394 }
2395
2396 intra_period.num_pframes = intraperiod_cfg.num_pframes;
2397 intra_period.num_bframes = intraperiod_cfg.num_bframes;
2398 return true;
2399}
2400
2401bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
2402{
2403 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2404 struct venc_entropycfg entropy_cfg;
2405
2406 memset(&entropy_cfg,0,sizeof(entropy_cfg));
2407 DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
2408
2409 if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){
2410 entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC;
2411 if (i_cabac_level == 0) {
2412 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
2413 }
2414#ifdef MAX_RES_1080P
2415 else
2416 {
2417 DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to model 0",i_cabac_level);
2418 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
2419 }
2420#else
2421 else if (i_cabac_level == 1) {
2422 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1;
2423 }
2424 else if (i_cabac_level == 2) {
2425 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2;
2426 }
2427#endif
2428 }
2429 else if(!enable){
2430 entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC;
2431 }
2432 else{
2433 DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
2434 return false;
2435 }
2436
2437 ioctl_msg.in = (void*)&entropy_cfg;
2438 ioctl_msg.out = NULL;
2439 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0)
2440 {
2441 DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed");
2442 return false;
2443 }
2444 entropy.longentropysel = entropy_cfg.longentropysel;
2445 entropy.cabacmodel = entropy_cfg.cabacmodel;
2446 return true;
2447}
2448
2449bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
2450{
2451 venc_ioctl_msg ioctl_msg = {NULL, NULL};
2452 bool status = true;
2453 struct venc_multiclicecfg multislice_cfg;
2454
2455 if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){
2456 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
2457 multislice_cfg.mslice_size = nSlicesize;
2458 }
2459 else{
2460 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
2461 multislice_cfg.mslice_size = 0;
2462 }
2463
2464 DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
2465 multislice_cfg.mslice_size);
2466
2467 ioctl_msg.in = (void*)&multislice_cfg;
2468 ioctl_msg.out = NULL;
2469 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0)
2470 {
2471 DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
2472 status = false;
2473 }
2474 else
2475 {
2476 multislice.mslice_mode = multislice_cfg.mslice_mode;
2477 multislice.mslice_size = nSlicesize;
2478 }
2479 return status;
2480}
2481
2482bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
2483{
2484 venc_ioctl_msg ioctl_msg = {NULL, NULL};
2485 bool status = true;
2486 struct venc_intrarefresh intraRefresh_cfg;
2487
2488 // There is no disabled mode. Disabled mode is indicated by a 0 count.
2489 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax)
2490 {
2491 intraRefresh_cfg.irmode = VEN_IR_OFF;
2492 intraRefresh_cfg.mbcount = 0;
2493 }
2494 else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
2495 (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
2496 {
2497 intraRefresh_cfg.irmode = VEN_IR_CYCLIC;
2498 intraRefresh_cfg.mbcount = irMBs;
2499 }
2500 else
2501 {
2502 DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
2503 "mb count: %d, mb mode:%d", irMBs, ir_mode);
2504 return false;
2505 }
2506
2507 ioctl_msg.in = (void*)&intraRefresh_cfg;
2508 ioctl_msg.out = NULL;
2509 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0)
2510 {
2511 DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed");
2512 status = false;
2513 }
2514 else
2515 {
2516 intra_refresh.irmode = intraRefresh_cfg.irmode;
2517 intra_refresh.mbcount = intraRefresh_cfg.mbcount;
2518 }
2519 return status;
2520}
2521
2522bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
2523{
2524 venc_ioctl_msg ioctl_msg = {NULL, NULL};
2525 bool status = true;
2526 struct venc_headerextension hec_cfg;
2527 struct venc_multiclicecfg multislice_cfg;
2528
2529 if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) {
2530 if (error_resilience->bEnableHEC) {
2531 hec_cfg.header_extension = 1;
2532 }
2533 else {
2534 hec_cfg.header_extension = 0;
2535 }
2536
2537 ioctl_msg.in = (void*)&hec_cfg;
2538 ioctl_msg.out = NULL;
2539 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) {
2540 DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed");
2541 return false;
2542 }
2543 hec.header_extension = error_resilience->bEnableHEC;
2544 }
2545
2546 if (error_resilience->bEnableRVLC) {
2547 DEBUG_PRINT_ERROR("\n RVLC is not Supported");
2548 return false;
2549 }
2550
2551 if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
2552 (error_resilience->bEnableDataPartitioning)) {
2553 DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
2554 return false;
2555 }
2556
2557 if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
2558 (error_resilience->nResynchMarkerSpacing)) {
2559 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
2560 multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
2561 }
2562 else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
2563 error_resilience->bEnableDataPartitioning) {
2564 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
2565 multislice_cfg.mslice_size = 0;
2566 }
2567 else {
2568 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
2569 multislice_cfg.mslice_size = 0;
2570 }
2571 DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
2572 multislice_cfg.mslice_size);
2573 ioctl_msg.in = (void*)&multislice_cfg;
2574 ioctl_msg.out = NULL;
2575 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
2576 DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
2577 status = false;
2578 }
2579 else
2580 {
2581 multislice.mslice_mode = multislice_cfg.mslice_mode ;
2582 multislice.mslice_size = multislice_cfg.mslice_size;
2583
2584 }
2585 return status;
2586}
2587
2588bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
2589{
2590 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2591 struct venc_dbcfg filter_cfg;
2592
2593 memset(&filter_cfg, 0, sizeof(filter_cfg));
2594 DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter);
2595
2596 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){
2597 filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY;
2598 }
2599 else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){
2600 filter_cfg.db_mode = VEN_DB_DISABLE;
2601 }
2602 else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){
2603 filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY;
2604 }
2605 filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0;
2606
2607 ioctl_msg.in = (void*)&filter_cfg;
2608 ioctl_msg.out = NULL;
2609 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0)
2610 {
2611 DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed");
2612 return false;
2613 }
2614
2615 dbkfilter.db_mode = filter_cfg.db_mode;
2616 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
2617 return true;
2618}
2619
2620bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
2621{
2622 venc_ioctl_msg ioctl_msg = {NULL, NULL};
2623 struct venc_targetbitrate bitrate_cfg;
2624
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302625 DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002626 nTargetBitrate);
2627 bitrate_cfg.target_bitrate = nTargetBitrate ;
2628 ioctl_msg.in = (void*)&bitrate_cfg;
2629 ioctl_msg.out = NULL;
2630 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0)
2631 {
2632 DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
2633 return false;
2634 }
2635 m_sVenc_cfg.targetbitrate = nTargetBitrate;
2636 bitrate.target_bitrate = nTargetBitrate;
2637 if(!config)
2638 {
2639 m_level_set = false;
2640 if(venc_set_profile_level(0, 0))
2641 {
2642 DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level);
2643 }
2644 }
2645 return true;
2646}
2647
2648bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
2649{
2650 venc_ioctl_msg ioctl_msg = {NULL, NULL};
2651 struct venc_framerate frame_rate_cfg;
2652
2653 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
2654
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302655 DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07002656 encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
2657
2658 ioctl_msg.in = (void*)&frame_rate_cfg;
2659 ioctl_msg.out = NULL;
2660 if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
2661 (void*)&ioctl_msg) < 0)
2662 {
2663 DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
2664 return false;
2665 }
2666
2667 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
2668 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
2669 if(!config)
2670 {
2671 m_level_set = false;
2672 if(venc_set_profile_level(0, 0))
2673 {
Maheshwar Ajja1c976422012-10-20 16:58:10 +05302674 DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675 }
2676 }
2677 return true;
2678}
2679
2680bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
2681{
2682 venc_ioctl_msg ioctl_msg = {NULL, NULL};
Shalaj Jain273b3e02012-06-22 19:08:03 -07002683 if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
2684 {
2685#ifdef MAX_RES_1080P
2686 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
2687#else
2688 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
2689#endif
2690 }
2691 else
2692 {
2693 DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
2694#ifdef MAX_RES_1080P
2695 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
2696#else
2697 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
2698#endif
2699 DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
2700 }
2701 ioctl_msg.in = (void*)&m_sVenc_cfg;
2702 ioctl_msg.out = NULL;
2703 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0)
2704 {
2705 DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
2706 return false;
2707 }
2708 return true;
2709}
2710
2711bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
2712{
2713 DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
2714 if(intra_vop_refresh == OMX_TRUE)
2715 {
2716 if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0)
2717 {
2718 DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
2719 return false;
2720 }
2721 }
2722 else
2723 {
2724 DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
2725 }
2726 return true;
2727}
2728
2729bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
2730{
2731 venc_ioctl_msg ioctl_msg = {NULL,NULL};
2732 bool status = true;
2733 struct venc_ratectrlcfg ratectrl_cfg;
2734
2735 //rate control
2736 switch(eControlRate)
2737 {
2738 case OMX_Video_ControlRateDisable:
2739 ratectrl_cfg.rcmode = VEN_RC_OFF;
2740 break;
2741 case OMX_Video_ControlRateVariableSkipFrames:
2742 ratectrl_cfg.rcmode = VEN_RC_VBR_VFR;
2743 break;
2744 case OMX_Video_ControlRateVariable:
2745 ratectrl_cfg.rcmode = VEN_RC_VBR_CFR;
2746 break;
2747 case OMX_Video_ControlRateConstantSkipFrames:
2748 ratectrl_cfg.rcmode = VEN_RC_CBR_VFR;
2749 break;
2750 case OMX_Video_ControlRateConstant:
2751 ratectrl_cfg.rcmode = VEN_RC_CBR_CFR;
2752 break;
2753 default:
2754 status = false;
2755 break;
2756 }
2757
2758 if(status)
2759 {
2760 ioctl_msg.in = (void*)&ratectrl_cfg;
2761 ioctl_msg.out = NULL;
2762 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0)
2763 {
2764 DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
2765 status = false;
2766 }
2767 else
2768 rate_ctrl.rcmode = ratectrl_cfg.rcmode;
2769 }
2770 return status;
2771}
2772
2773bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
2774{
2775 bool status = true;
2776 if(eProfile == NULL || eLevel == NULL)
2777 {
2778 return false;
2779 }
2780
2781 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
2782 {
2783 switch(codec_profile.profile)
2784 {
2785 case VEN_PROFILE_MPEG4_SP:
2786 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2787 break;
2788 case VEN_PROFILE_MPEG4_ASP:
2789 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2790 break;
2791 default:
2792 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
2793 status = false;
2794 break;
2795 }
2796
2797 if(!status)
2798 {
2799 return status;
2800 }
2801
2802 //profile level
2803 switch(profile_level.level)
2804 {
2805 case VEN_LEVEL_MPEG4_0:
2806 *eLevel = OMX_VIDEO_MPEG4Level0;
2807 break;
2808 case VEN_LEVEL_MPEG4_1:
2809 *eLevel = OMX_VIDEO_MPEG4Level1;
2810 break;
2811 case VEN_LEVEL_MPEG4_2:
2812 *eLevel = OMX_VIDEO_MPEG4Level2;
2813 break;
2814 case VEN_LEVEL_MPEG4_3:
2815 *eLevel = OMX_VIDEO_MPEG4Level3;
2816 break;
2817 case VEN_LEVEL_MPEG4_4:
2818 *eLevel = OMX_VIDEO_MPEG4Level4a;
2819 break;
2820 case VEN_LEVEL_MPEG4_5:
2821 case VEN_LEVEL_MPEG4_6:
2822 *eLevel = OMX_VIDEO_MPEG4Level5;
2823 break;
2824 default:
2825 *eLevel = OMX_VIDEO_MPEG4LevelMax;
2826 status = false;
2827 break;
2828 }
2829 }
2830 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
2831 {
2832 if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
2833 {
2834 *eProfile = OMX_VIDEO_H263ProfileBaseline;
2835 }
2836 else
2837 {
2838 *eProfile = OMX_VIDEO_H263ProfileMax;
2839 return false;
2840 }
2841 switch(profile_level.level)
2842 {
2843 case VEN_LEVEL_H263_10:
2844 *eLevel = OMX_VIDEO_H263Level10;
2845 break;
2846 case VEN_LEVEL_H263_20:
2847 *eLevel = OMX_VIDEO_H263Level20;
2848 break;
2849 case VEN_LEVEL_H263_30:
2850 *eLevel = OMX_VIDEO_H263Level30;
2851 break;
2852 case VEN_LEVEL_H263_40:
2853 *eLevel = OMX_VIDEO_H263Level40;
2854 break;
2855 case VEN_LEVEL_H263_45:
2856 *eLevel = OMX_VIDEO_H263Level45;
2857 break;
2858 case VEN_LEVEL_H263_50:
2859 *eLevel = OMX_VIDEO_H263Level50;
2860 break;
2861 case VEN_LEVEL_H263_60:
2862 *eLevel = OMX_VIDEO_H263Level60;
2863 break;
2864 case VEN_LEVEL_H263_70:
2865 *eLevel = OMX_VIDEO_H263Level70;
2866 break;
2867 default:
2868 *eLevel = OMX_VIDEO_H263LevelMax;
2869 status = false;
2870 break;
2871 }
2872 }
2873 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
2874 {
2875 switch(codec_profile.profile)
2876 {
2877 case VEN_PROFILE_H264_BASELINE:
2878 *eProfile = OMX_VIDEO_AVCProfileBaseline;
2879 break;
2880 case VEN_PROFILE_H264_MAIN:
2881 *eProfile = OMX_VIDEO_AVCProfileMain;
2882 break;
2883 case VEN_PROFILE_H264_HIGH:
2884 *eProfile = OMX_VIDEO_AVCProfileHigh;
2885 break;
2886 default:
2887 *eProfile = OMX_VIDEO_AVCProfileMax;
2888 status = false;
2889 break;
2890 }
2891
2892 if(!status)
2893 {
2894 return status;
2895 }
2896
2897 switch(profile_level.level)
2898 {
2899 case VEN_LEVEL_H264_1:
2900 *eLevel = OMX_VIDEO_AVCLevel1;
2901 break;
2902 case VEN_LEVEL_H264_1b:
2903 *eLevel = OMX_VIDEO_AVCLevel1b;
2904 break;
2905 case VEN_LEVEL_H264_1p1:
2906 *eLevel = OMX_VIDEO_AVCLevel11;
2907 break;
2908 case VEN_LEVEL_H264_1p2:
2909 *eLevel = OMX_VIDEO_AVCLevel12;
2910 break;
2911 case VEN_LEVEL_H264_1p3:
2912 *eLevel = OMX_VIDEO_AVCLevel13;
2913 break;
2914 case VEN_LEVEL_H264_2:
2915 *eLevel = OMX_VIDEO_AVCLevel2;
2916 break;
2917 case VEN_LEVEL_H264_2p1:
2918 *eLevel = OMX_VIDEO_AVCLevel21;
2919 break;
2920 case VEN_LEVEL_H264_2p2:
2921 *eLevel = OMX_VIDEO_AVCLevel22;
2922 break;
2923 case VEN_LEVEL_H264_3:
2924 *eLevel = OMX_VIDEO_AVCLevel3;
2925 break;
2926 case VEN_LEVEL_H264_3p1:
2927 *eLevel = OMX_VIDEO_AVCLevel31;
2928 break;
2929 case VEN_LEVEL_H264_3p2:
2930 *eLevel = OMX_VIDEO_AVCLevel32;
2931 break;
2932 case VEN_LEVEL_H264_4:
2933 *eLevel = OMX_VIDEO_AVCLevel4;
2934 break;
2935 default :
2936 *eLevel = OMX_VIDEO_AVCLevelMax;
2937 status = false;
2938 break;
2939 }
2940 }
2941 return status;
2942}
2943
2944bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
2945{
2946 OMX_U32 new_profile = 0, new_level = 0;
2947 unsigned const int *profile_tbl = NULL;
2948 OMX_U32 mb_per_frame, mb_per_sec;
2949 bool profile_level_found = false;
2950
2951 DEBUG_PRINT_LOW("\n Init profile table for respective codec");
2952 //validate the ht,width,fps,bitrate and set the appropriate profile and level
2953 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
2954 {
2955 if(*eProfile == 0)
2956 {
2957 if(!m_profile_set)
2958 {
2959 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2960 }
2961 else
2962 {
2963 switch(codec_profile.profile)
2964 {
2965 case VEN_PROFILE_MPEG4_ASP:
2966 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2967 break;
2968 case VEN_PROFILE_MPEG4_SP:
2969 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2970 break;
2971 default:
2972 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
2973 return false;
2974 }
2975 }
2976 }
2977
2978 if(*eLevel == 0 && !m_level_set)
2979 {
2980 *eLevel = OMX_VIDEO_MPEG4LevelMax;
2981 }
2982
2983 if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
2984 {
2985 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
2986 }
2987 else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
2988 {
2989 profile_tbl = (unsigned int const *)
2990 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
2991 }
2992 else
2993 {
2994 DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
2995 return false;
2996 }
2997 }
2998 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
2999 {
3000 if(*eProfile == 0)
3001 {
3002 if(!m_profile_set)
3003 {
3004 *eProfile = OMX_VIDEO_AVCProfileBaseline;
3005 }
3006 else
3007 {
3008 switch(codec_profile.profile)
3009 {
3010 case VEN_PROFILE_H264_BASELINE:
3011 *eProfile = OMX_VIDEO_AVCProfileBaseline;
3012 break;
3013 case VEN_PROFILE_H264_MAIN:
3014 *eProfile = OMX_VIDEO_AVCProfileMain;
3015 break;
3016 case VEN_PROFILE_H264_HIGH:
3017 *eProfile = OMX_VIDEO_AVCProfileHigh;
3018 break;
3019 default:
3020 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
3021 return false;
3022 }
3023 }
3024 }
3025
3026 if(*eLevel == 0 && !m_level_set)
3027 {
3028 *eLevel = OMX_VIDEO_AVCLevelMax;
3029 }
3030
3031 if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
3032 {
3033 profile_tbl = (unsigned int const *)h264_profile_level_table;
3034 }
3035 else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
3036 {
3037 profile_tbl = (unsigned int const *)
3038 (&h264_profile_level_table[H264_HP_START]);
3039 }
3040 else if(*eProfile == OMX_VIDEO_AVCProfileMain)
3041 {
3042 profile_tbl = (unsigned int const *)
3043 (&h264_profile_level_table[H264_MP_START]);
3044 }
3045 else
3046 {
3047 DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
3048 return false;
3049 }
3050 }
3051 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
3052 {
3053 if(*eProfile == 0)
3054 {
3055 if(!m_profile_set)
3056 {
3057 *eProfile = OMX_VIDEO_H263ProfileBaseline;
3058 }
3059 else
3060 {
3061 switch(codec_profile.profile)
3062 {
3063 case VEN_PROFILE_H263_BASELINE:
3064 *eProfile = OMX_VIDEO_H263ProfileBaseline;
3065 break;
3066 default:
3067 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
3068 return false;
3069 }
3070 }
3071 }
3072
3073 if(*eLevel == 0 && !m_level_set)
3074 {
3075 *eLevel = OMX_VIDEO_H263LevelMax;
3076 }
3077
3078 if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
3079 {
3080 profile_tbl = (unsigned int const *)h263_profile_level_table;
3081 }
3082 else
3083 {
3084 DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
3085 return false;
3086 }
3087 }
3088 else
3089 {
3090 DEBUG_PRINT_LOW("\n Invalid codec type");
3091 return false;
3092 }
3093
3094 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
3095 ((m_sVenc_cfg.input_width + 15)>> 4);
3096
3097 if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4))
3098 {
3099 if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP)
3100 profile_level.level = VEN_LEVEL_MPEG4_5;
3101 if(codec_profile.profile == VEN_PROFILE_MPEG4_SP)
3102 profile_level.level = VEN_LEVEL_MPEG4_6;
3103 {
3104 new_level = profile_level.level;
3105 new_profile = codec_profile.profile;
3106 return true;
3107 }
3108 }
3109
3110 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
3111
3112 do{
3113 if(mb_per_frame <= (int)profile_tbl[0])
3114 {
3115 if(mb_per_sec <= (int)profile_tbl[1])
3116 {
3117 if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
3118 {
3119 new_level = (int)profile_tbl[3];
3120 new_profile = (int)profile_tbl[4];
3121 profile_level_found = true;
3122 DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
3123 break;
3124 }
3125 }
3126 }
3127 profile_tbl = profile_tbl + 5;
3128 }while(profile_tbl[0] != 0);
3129
3130 if (profile_level_found != true)
3131 {
3132 DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
3133 return false;
3134 }
3135
3136 if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
3137 || (*eLevel == OMX_VIDEO_H263LevelMax))
3138 {
3139 *eLevel = new_level;
3140 }
3141 DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu"
3142 "Level = %lu", __func__, *eProfile, *eLevel);
3143
3144 return true;
3145}
3146
3147bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate)
3148{
3149 unsigned const int *profile_tbl = NULL;
3150
3151 switch(m_sVenc_cfg.codectype)
3152 {
3153 case VEN_CODEC_MPEG4:
3154 if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple)
3155 {
3156 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
3157 }
3158 else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
3159 {
3160 profile_tbl = (unsigned int const *)
3161 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
3162 }
3163 else
3164 {
3165 DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile);
3166 return false;
3167 }
3168 break;
3169 case VEN_CODEC_H264:
3170 if(m_eProfile == OMX_VIDEO_AVCProfileBaseline)
3171 {
3172 profile_tbl = (unsigned int const *)h264_profile_level_table;
3173 }
3174 else if(m_eProfile == OMX_VIDEO_AVCProfileHigh)
3175 {
3176 profile_tbl = (unsigned int const *)
3177 (&h264_profile_level_table[H264_HP_START]);
3178 }
3179 else if(m_eProfile == OMX_VIDEO_AVCProfileMain)
3180 {
3181 profile_tbl = (unsigned int const *)
3182 (&h264_profile_level_table[H264_MP_START]);
3183 }
3184 else
3185 {
3186 DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile);
3187 return false;
3188 }
3189
3190 break;
3191 case VEN_CODEC_H263:
3192 if(m_eProfile == OMX_VIDEO_H263ProfileBaseline)
3193 {
3194 profile_tbl = (unsigned int const *)h263_profile_level_table;
3195 }
3196 else
3197 {
3198 DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile);
3199 return false;
3200 }
3201 break;
3202 default:
3203 DEBUG_PRINT_ERROR("%s: unknown codec type", __func__);
3204 return false;
3205 }
3206 while(profile_tbl[0] != 0)
3207 {
3208 if(profile_tbl[3] == m_eLevel)
3209 {
3210 if(nTargetBitrate > profile_tbl[2])
3211 {
3212 DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]"
3213 " is %u", m_eProfile, m_eLevel, profile_tbl[2]);
3214 return false;
3215 }
3216 }
3217 profile_tbl += 5;
3218 }
3219 return true;
3220}
3221
3222#ifdef _ANDROID_ICS_
3223bool venc_dev::venc_set_meta_mode(bool mode)
3224{
3225 venc_ioctl_msg ioctl_msg = {NULL,NULL};
3226 ioctl_msg.in = &mode;
3227 DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode);
3228 if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0)
3229 {
3230 DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
3231 return false;
3232 }
3233 return true;
3234}
3235#endif