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