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