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