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