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