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