1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of The Linux Foundation nor
12 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/prctl.h>
32 #include <sys/eventfd.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include "video_encoder_device_v4l2.h"
36 #include "omx_video_encoder.h"
37 #include <media/msm_vidc.h>
38 #ifdef USE_ION
39 #include <linux/msm_ion.h>
40 #endif
41 #include <media/msm_media_info.h>
42 #include <cutils/properties.h>
43 #include <media/hardware/HardwareAPI.h>
44
45 #ifdef _ANDROID_
46 #include <media/hardware/HardwareAPI.h>
47 #include <gralloc_priv.h>
48 #endif
49
50 #include <qdMetaData.h>
51
52 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
53 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
54 #define MAXDPB 16
55 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
56 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
57 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
58 #define MAX_PROFILE_PARAMS 6
59 #define MPEG4_SP_START 0
60 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
61 #define H263_BP_START 0
62 #define H264_BP_START 0
63 #define H264_HP_START (H264_BP_START + 18)
64 #define H264_MP_START (H264_BP_START + 36)
65 #define HEVC_MAIN_START 0
66 #define HEVC_MAIN10_START (HEVC_MAIN_START + 13)
67 #define POLL_TIMEOUT 1000
68 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
69
70 #define SZ_4K 0x1000
71 #define SZ_1M 0x100000
72
73 /* MPEG4 profile and level table*/
74 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
75 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
76 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
77 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
78 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
79 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
80 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
81 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
82 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
83 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
84 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
85 /* Please update MPEG4_ASP_START accordingly, while adding new element */
86 {0,0,0,0,0,0},
87
88 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
89 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
90 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
91 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
92 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
93 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
94 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
95 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
96 {0,0,0,0,0,0},
97 };
98
99 /* H264 profile and level table*/
100 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
101 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
102 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
103 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
104 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
105 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
106 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
107 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
108 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
109 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
110 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
111 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
112 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
113 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
114 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
115 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
116 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
117 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
118 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
119 /* Please update H264_HP_START accordingly, while adding new element */
120 {0,0,0,0,0,0},
121
122 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
123 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
124 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
125 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
126 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
127 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
128 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
129 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
130 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
131 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
132 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
133 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
134 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
135 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
136 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
137 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
138 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
139 /* Please update H264_MP_START accordingly, while adding new element */
140 {0,0,0,0,0,0},
141
142 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
143 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
144 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
145 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
146 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
147 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
148 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
149 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
150 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
151 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
152 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
153 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
154 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
155 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
156 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
157 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
158 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
159 {0,0,0,0,0,0}
160
161 };
162
163 /* H263 profile and level table*/
164 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
165 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
166 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
167 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
168 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
169 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
170 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
171 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
172 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
173 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
174 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
175 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
176 {0,0,0,0,0,0}
177 };
178
179 /* HEVC profile and level table*/
180 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
181 /*max mb per frame, max mb per sec, max bitrate, level, profile*/
182 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
183 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
184 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
185 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
186 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
187 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
188 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
189 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
190 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
191 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
192 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
193 {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
194 {138240,4147200,240000000,OMX_VIDEO_HEVCHighTierLevel52,OMX_VIDEO_HEVCProfileMain,0},
195 /* Please update HEVC_MAIN_START accordingly, while adding new element */
196 {0,0,0,0,0},
197
198 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
199 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
200 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
201 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
202 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
203 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
204 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
205 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
206 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
207 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
208 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
209 {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
210 {0,0,0,0,0},
211 };
212
213
214 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
215 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
216
217 #define BUFFER_LOG_LOC "/data/misc/media"
218
219 //constructor
venc_dev(class omx_venc * venc_class)220 venc_dev::venc_dev(class omx_venc *venc_class):mInputExtradata(venc_class), mOutputExtradata(venc_class)
221 {
222 //nothing to do
223 int i = 0;
224 venc_handle = venc_class;
225 etb = ebd = ftb = fbd = 0;
226 m_poll_efd = -1;
227
228 struct v4l2_control control;
229 for (i = 0; i < MAX_PORT; i++)
230 streaming[i] = false;
231
232 stopped = 1;
233 paused = false;
234 async_thread_created = false;
235 async_thread_force_stop = false;
236 color_format = 0;
237 hw_overload = false;
238 mBatchSize = 0;
239 m_profile_set = false;
240 m_level_set = false;
241 rc_off_level = 0;
242 pthread_mutex_init(&pause_resume_mlock, NULL);
243 pthread_cond_init(&pause_resume_cond, NULL);
244 memset(&idrperiod, 0, sizeof(idrperiod));
245 memset(&multislice, 0, sizeof(multislice));
246 memset (&slice_mode, 0 , sizeof(slice_mode));
247 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
248 memset(&rate_ctrl, 0, sizeof(rate_ctrl));
249 memset(&bitrate, 0, sizeof(bitrate));
250 memset(&intra_period, 0, sizeof(intra_period));
251 memset(&codec_profile, 0, sizeof(codec_profile));
252 memset(&set_param, 0, sizeof(set_param));
253 memset(&time_inc, 0, sizeof(time_inc));
254 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
255 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
256 memset(&session_qp, 0, sizeof(session_qp));
257 memset(&entropy, 0, sizeof(entropy));
258 memset(&dbkfilter, 0, sizeof(dbkfilter));
259 memset(&intra_refresh, 0, sizeof(intra_refresh));
260 memset(&hec, 0, sizeof(hec));
261 memset(&voptimecfg, 0, sizeof(voptimecfg));
262 memset(&capability, 0, sizeof(capability));
263 memset(&m_debug,0,sizeof(m_debug));
264 memset(&hier_layers,0,sizeof(hier_layers));
265 is_searchrange_set = false;
266 enable_mv_narrow_searchrange = false;
267 supported_rc_modes = RC_ALL;
268 memset(&vqzip_sei_info, 0, sizeof(vqzip_sei_info));
269 memset(<rinfo, 0, sizeof(ltrinfo));
270 memset(&fd_list, 0, sizeof(fd_list));
271 memset(&hybrid_hp, 0, sizeof(hybrid_hp));
272 sess_priority.priority = 1; //default to non-realtime
273 operating_rate = 0;
274 memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
275 memset(&color_space, 0x0, sizeof(color_space));
276
277 char property_value[PROPERTY_VALUE_MAX] = {0};
278 property_get("vidc.enc.log.in", property_value, "0");
279 m_debug.in_buffer_log = atoi(property_value);
280
281 property_get("vidc.enc.log.out", property_value, "0");
282 m_debug.out_buffer_log = atoi(property_value);
283
284 property_get("vidc.enc.log.extradata", property_value, "0");
285 m_debug.extradata_log = atoi(property_value);
286
287 property_get("vidc.enc.log.roiqp", property_value, "0");
288 m_debug.roiqp_log = atoi(property_value);
289 #ifdef _UBWC_
290 property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
291 if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
292 !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
293 is_gralloc_source_ubwc = 0;
294 } else {
295 is_gralloc_source_ubwc = 1;
296 }
297 #else
298 is_gralloc_source_ubwc = 0;
299 #endif
300
301 property_get("persist.vidc.enc.csc.enable", property_value, "0");
302 if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
303 !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
304 is_csc_enabled = 1;
305 } else {
306 is_csc_enabled = 0;
307 }
308 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
309 "%s", BUFFER_LOG_LOC);
310
311 mUseAVTimerTimestamps = false;
312 }
313
~venc_dev()314 venc_dev::~venc_dev()
315 {
316 }
317
async_venc_message_thread(void * input)318 void* venc_dev::async_venc_message_thread (void *input)
319 {
320 struct venc_msg venc_msg;
321 omx_video* omx_venc_base = NULL;
322 omx_venc *omx = reinterpret_cast<omx_venc*>(input);
323 omx_venc_base = reinterpret_cast<omx_video*>(input);
324 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
325
326 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
327 struct v4l2_plane plane[VIDEO_MAX_PLANES];
328 struct pollfd pfds[2];
329 struct v4l2_buffer v4l2_buf;
330 struct v4l2_event dqevent;
331 struct statistics stats;
332 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
333 pfds[1].events = POLLIN | POLLERR;
334 pfds[0].fd = omx->handle->m_nDriver_fd;
335 pfds[1].fd = omx->handle->m_poll_efd;
336 int error_code = 0,rc=0;
337
338 memset(&stats, 0, sizeof(statistics));
339 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
340
341 while (!omx->handle->async_thread_force_stop) {
342 pthread_mutex_lock(&omx->handle->pause_resume_mlock);
343
344 if (omx->handle->paused) {
345 venc_msg.msgcode = VEN_MSG_PAUSE;
346 venc_msg.statuscode = VEN_S_SUCCESS;
347
348 if (omx->async_message_process(input, &venc_msg) < 0) {
349 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
350 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
351 break;
352 }
353
354 /* Block here until the IL client resumes us again */
355 pthread_cond_wait(&omx->handle->pause_resume_cond,
356 &omx->handle->pause_resume_mlock);
357
358 venc_msg.msgcode = VEN_MSG_RESUME;
359 venc_msg.statuscode = VEN_S_SUCCESS;
360
361 if (omx->async_message_process(input, &venc_msg) < 0) {
362 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
363 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
364 break;
365 }
366 memset(&stats, 0, sizeof(statistics));
367 }
368
369 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
370
371 rc = poll(pfds, 2, POLL_TIMEOUT);
372
373 if (!rc) {
374 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
375 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
376 continue;
377 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
378 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
379 break;
380 }
381
382 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
383 DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited");
384 break;
385 }
386
387 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
388 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
389 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
390 v4l2_buf.length = omx->handle->num_output_planes;
391 v4l2_buf.m.planes = plane;
392
393 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
394 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
395 venc_msg.statuscode=VEN_S_SUCCESS;
396 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
397 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
398 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
399 omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
400 } else {
401 omxhdr->pPlatformPrivate = 0;
402 }
403 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
404 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
405 venc_msg.buf.flags = 0;
406 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
407 venc_msg.buf.clientdata=(void*)omxhdr;
408 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
409
410 /* TODO: ideally report other types of frames as well
411 * for now it doesn't look like IL client cares about
412 * other types
413 */
414 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
415 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
416
417 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
418 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
419
420 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
421 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
422
423 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
424 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
425
426 if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused)
427 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
428
429 if (omxhdr->nFilledLen)
430 venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
431
432 omx->handle->fbd++;
433 stats.bytes_generated += venc_msg.buf.len;
434
435 if (omx->async_message_process(input,&venc_msg) < 0) {
436 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
437 break;
438 }
439 }
440 }
441
442 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
443 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
444 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
445 v4l2_buf.m.planes = plane;
446 v4l2_buf.length = omx->handle->num_input_planes;
447
448 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
449 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
450 venc_msg.statuscode=VEN_S_SUCCESS;
451 omx->handle->ebd++;
452
453 if (omx->handle->mBatchSize) {
454 int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index);
455 if (bufIndex < 0) {
456 DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index);
457 break;
458 }
459 if (omx->handle->mBatchInfo.isPending(bufIndex)) {
460 DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending",
461 bufIndex, v4l2_buf.index);
462 //do not return to client yet
463 continue;
464 }
465 v4l2_buf.index = bufIndex;
466 }
467 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
468 omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
469 else
470 omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
471
472 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
473 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
474 omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
475 omx->handle->mInputExtradata.put((char *)omxhdr->pPlatformPrivate);
476 } else {
477 omxhdr->pPlatformPrivate = 0;
478 }
479
480 venc_msg.buf.clientdata=(void*)omxhdr;
481
482 DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index);
483 if (omx->async_message_process(input,&venc_msg) < 0) {
484 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
485 break;
486 }
487 }
488 }
489
490 if (pfds[0].revents & POLLPRI) {
491 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
492
493 if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
494 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
495 venc_msg.statuscode = VEN_S_SUCCESS;
496
497 if (omx->async_message_process(input,&venc_msg) < 0) {
498 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
499 break;
500 }
501
502 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
503 venc_msg.statuscode = VEN_S_SUCCESS;
504
505 if (omx->async_message_process(input,&venc_msg) < 0) {
506 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
507 break;
508 }
509 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
510 DEBUG_PRINT_ERROR("HW Overload received");
511 venc_msg.statuscode = VEN_S_EFAIL;
512 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
513
514 if (omx->async_message_process(input,&venc_msg) < 0) {
515 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
516 break;
517 }
518 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){
519 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
520 venc_msg.msgcode = VEN_MSG_INDICATION;
521 venc_msg.statuscode=VEN_S_EFAIL;
522
523 if (omx->async_message_process(input,&venc_msg) < 0) {
524 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
525 break;
526 }
527 }
528 }
529
530 /* calc avg. fps, bitrate */
531 struct timeval tv;
532 gettimeofday(&tv,NULL);
533 OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) -
534 (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec));
535 if (time_diff >= 5000000) {
536 if (stats.prev_tv.tv_sec) {
537 OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd;
538 float framerate = num_fbd * 1000000/(float)time_diff;
539 OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate;
540 DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d",
541 framerate, bitrate);
542 }
543 stats.prev_tv = tv;
544 stats.bytes_generated = 0;
545 stats.prev_fbd = omx->handle->fbd;
546 }
547
548 }
549
550 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
551 return NULL;
552 }
553
554 static const int event_type[] = {
555 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
556 V4L2_EVENT_MSM_VIDC_SYS_ERROR
557 };
558
subscribe_to_events(int fd)559 static OMX_ERRORTYPE subscribe_to_events(int fd)
560 {
561 OMX_ERRORTYPE eRet = OMX_ErrorNone;
562 struct v4l2_event_subscription sub;
563 int array_sz = sizeof(event_type)/sizeof(int);
564 int i,rc;
565 memset(&sub, 0, sizeof(sub));
566
567 if (fd < 0) {
568 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
569 return OMX_ErrorBadParameter;
570 }
571
572 for (i = 0; i < array_sz; ++i) {
573 memset(&sub, 0, sizeof(sub));
574 sub.type = event_type[i];
575 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
576
577 if (rc) {
578 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
579 break;
580 }
581 }
582
583 if (i < array_sz) {
584 for (--i; i >=0 ; i--) {
585 memset(&sub, 0, sizeof(sub));
586 sub.type = event_type[i];
587 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
588
589 if (rc)
590 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
591 }
592
593 eRet = OMX_ErrorNotImplemented;
594 }
595
596 return eRet;
597 }
598
append_mbi_extradata(void * dst,struct msm_vidc_extradata_header * src)599 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
600 {
601 OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
602
603 if (!dst || !src)
604 return 0;
605
606 /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
607 * targets, since the payload format will be different */
608 mbi->nFormat = 1;
609 mbi->nDataSize = src->data_size;
610 memcpy(&mbi->data, &src->data, src->data_size);
611
612 return mbi->nDataSize + sizeof(*mbi);
613 }
614
handle_input_extradata(void * buffer,int fd)615 bool venc_dev::handle_input_extradata(void *buffer, int fd)
616 {
617 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
618 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
619 ssize_t consumed_len = 0;
620 int enable = 0, i = 0;
621 int height = 0, width = 0;
622 char *userptr;
623 int extra_fd;
624 unsigned offset;
625 ssize_t extra_size;
626 struct v4l2_control control;
627
628 memset(&control, 0, sizeof(control));
629 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
630 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control) < 0) {
631 return false;
632 }
633
634 if (!(control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
635 control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI ||
636 control.value == V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP ||
637 control.value == V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP)) {
638 DEBUG_PRINT_LOW("Input extradata not enabled");
639 return true;
640 }
641
642 /*
643 * At this point encoder component doesn't know where the extradata is
644 * located in YUV buffer. For all practical usecases, decoder appends
645 * extradata after nFilledLen which is calcualted as 32 aligned height
646 * and width * 3 / 2. Hence start looking for extradata from this point.
647 */
648
649 height = ALIGN(m_sVenc_cfg.input_height, 32);
650 width = ALIGN(m_sVenc_cfg.input_width, 32);
651
652 int rc = mInputExtradata.get(buffer, &userptr, &extra_fd, &offset, &extra_size);
653 if (rc != OMX_ErrorNone) {
654 DEBUG_PRINT_ERROR("Unable to get extradata memory 4");
655 return false;
656 }
657 unsigned char *pVirt;
658 int size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
659 pVirt= (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
660
661 p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned long)(pVirt + ((width * height * 3) / 2) + 3)&(~3));
662 char *p_extradata = userptr;
663 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
664 if (p_extra) {
665 while ((consumed_len < extra_size)
666 && (p_extra->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
667 DEBUG_PRINT_LOW("Extradata Type = 0x%x", (OMX_QCOM_EXTRADATATYPE)p_extra->eType);
668 switch ((OMX_QCOM_EXTRADATATYPE)p_extra->eType) {
669 case OMX_ExtraDataFrameDimension:
670 {
671 struct msm_vidc_extradata_index *payload;
672 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *framedimension_format;
673 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_extradata_index) + 3)&(~3);
674 data->nVersion.nVersion = OMX_SPEC_VERSION;
675 data->nPortIndex = 0;
676 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_INDEX;
677 data->nDataSize = sizeof(struct msm_vidc_input_crop_payload);
678 framedimension_format = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)p_extra->data;
679 payload = (struct msm_vidc_extradata_index *)(data->data);
680 payload->type = (msm_vidc_extradata_type)MSM_VIDC_EXTRADATA_INPUT_CROP;
681 payload->input_crop.left = framedimension_format->nDecWidth;
682 payload->input_crop.top = framedimension_format->nDecHeight;
683 payload->input_crop.width = framedimension_format->nActualWidth;
684 payload->input_crop.height = framedimension_format->nActualHeight;
685 DEBUG_PRINT_LOW("Height = %d Width = %d Actual Height = %d Actual Width = %d",
686 framedimension_format->nDecWidth, framedimension_format->nDecHeight,
687 framedimension_format->nActualWidth, framedimension_format->nActualHeight);
688 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
689 break;
690 }
691 case OMX_ExtraDataQP:
692 {
693 OMX_QCOM_EXTRADATA_QP * qp_payload = NULL;
694 struct msm_vidc_frame_qp_payload *payload;
695 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_frame_qp_payload) + 3)&(~3);
696 data->nVersion.nVersion = OMX_SPEC_VERSION;
697 data->nPortIndex = 0;
698 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_FRAME_QP;
699 data->nDataSize = sizeof(struct msm_vidc_frame_qp_payload);
700 qp_payload = (OMX_QCOM_EXTRADATA_QP *)p_extra->data;
701 payload = (struct msm_vidc_frame_qp_payload *)(data->data);
702 payload->frame_qp = qp_payload->nQP;
703 DEBUG_PRINT_LOW("Frame QP = %d", payload->frame_qp);
704 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
705 break;
706 }
707 case OMX_ExtraDataVQZipSEI:
708 DEBUG_PRINT_LOW("VQZIP SEI Found ");
709 mInputExtradata.vqzip_sei_found = true;
710 break;
711 default:
712 break;
713 }
714 consumed_len += p_extra->nSize;
715 p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize);
716 }
717
718 if (control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
719 control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI) {
720 if (!mInputExtradata.vqzip_sei_found) {
721 DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session");
722 munmap(pVirt, size);
723 mInputExtradata.put(userptr);
724 return false;
725 }
726 #ifdef _VQZIP_
727 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct VQZipStats) + 3)&(~3);
728 data->nVersion.nVersion = OMX_SPEC_VERSION;
729 data->nPortIndex = 0;
730 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_YUVSTATS_INFO;
731 data->nDataSize = sizeof(struct VQZipStats);
732 vqzip.fill_stats_data((void*)pVirt, (void*) data->data);
733 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
734 #endif
735 }
736
737 data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
738 data->nVersion.nVersion = OMX_SPEC_VERSION;
739 data->eType = OMX_ExtraDataNone;
740 data->nDataSize = 0;
741 data->data[0] = 0;
742
743 }
744 munmap(pVirt, size);
745 mInputExtradata.put(userptr);
746 return true;
747 }
748
handle_output_extradata(void * buffer)749 bool venc_dev::handle_output_extradata(void *buffer)
750 {
751 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
752 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
753 char *extradata_uaddr = (char *)p_bufhdr->pPlatformPrivate;
754
755 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
756 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
757
758 if (mOutputExtradata.getBufferSize() >
759 (ssize_t)(p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4))) {
760 DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
761 p_extra = NULL;
762 return false;
763 } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
764 /* A lot of the code below assumes this condition, so error out if it's not met */
765 DEBUG_PRINT_ERROR("Extradata ABI mismatch");
766 return false;
767 }
768
769 struct msm_vidc_extradata_header *p_extradata = NULL;
770 do {
771 p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
772 ((char *)p_extradata) + p_extradata->size : extradata_uaddr);
773
774 switch (p_extradata->type) {
775 case MSM_VIDC_EXTRADATA_METADATA_MBI:
776 {
777 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
778 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
779 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
780 p_extra->nPortIndex = OMX_DirOutput;
781 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
782 p_extra->nDataSize = payloadSize;
783 break;
784 }
785 case MSM_VIDC_EXTRADATA_METADATA_LTR:
786 {
787 *p_extra->data = *p_extradata->data;
788 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
789 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
790 p_extra->nPortIndex = OMX_DirOutput;
791 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
792 p_extra->nDataSize = p_extradata->data_size;
793 break;
794 }
795 case MSM_VIDC_EXTRADATA_NONE:
796 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
797 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
798 p_extra->nPortIndex = OMX_DirOutput;
799 p_extra->eType = OMX_ExtraDataNone;
800 p_extra->nDataSize = 0;
801 break;
802 default:
803 /* No idea what this stuff is, just skip over it */
804 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
805 p_extradata->type);
806 continue;
807 }
808
809 p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
810 } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
811
812 /* Just for debugging: Traverse the list of extra datas and spit it out onto log */
813 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
814 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
815 while(p_extra->eType != OMX_ExtraDataNone)
816 {
817 DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
818 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
819 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
820
821 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
822 p_extra->nSize);
823 }
824 mOutputExtradata.put(extradata_uaddr);
825 return true;
826 }
827
venc_set_format(int format)828 int venc_dev::venc_set_format(int format)
829 {
830 int rc = true;
831
832 if (format) {
833 color_format = format;
834
835 switch (color_format) {
836 case NV12_128m:
837 return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m);
838 default:
839 return false;
840 }
841
842 } else {
843 color_format = 0;
844 rc = false;
845 }
846
847 return rc;
848 }
849
venc_get_output_log_flag()850 bool venc_dev::venc_get_output_log_flag()
851 {
852 return (m_debug.out_buffer_log == 1);
853 }
854
venc_output_log_buffers(const char * buffer_addr,int buffer_len)855 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
856 {
857 if (venc_handle->is_secure_session()) {
858 DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
859 return -1;
860 }
861
862 if (!m_debug.outfile) {
863 int size = 0;
864 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
865 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
866 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
867 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
868 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
869 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
870 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
871 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
872 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
873 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
874 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
875 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
876 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
877 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
878 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
879 }
880 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
881 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
882 m_debug.outfile_name, size);
883 }
884 m_debug.outfile = fopen(m_debug.outfile_name, "ab");
885 if (!m_debug.outfile) {
886 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
887 m_debug.outfile_name, errno);
888 m_debug.outfile_name[0] = '\0';
889 return -1;
890 }
891 }
892 if (m_debug.outfile && buffer_len) {
893 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
894 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
895 }
896 return 0;
897 }
898
venc_extradata_log_buffers(char * buffer_addr)899 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
900 {
901 if (!m_debug.extradatafile && m_debug.extradata_log) {
902 int size = 0;
903 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
904 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
905 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
906 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
907 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
908 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
909 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
910 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
911 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
912 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
913 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
914 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
915 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
916 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
917 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
918 }
919 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
920 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
921 m_debug.extradatafile_name, size);
922 }
923
924 m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
925 if (!m_debug.extradatafile) {
926 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
927 m_debug.extradatafile_name, errno);
928 m_debug.extradatafile_name[0] = '\0';
929 return -1;
930 }
931 }
932
933 if (m_debug.extradatafile) {
934 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
935 do {
936 p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
937 ((char *)p_extra) + p_extra->nSize);
938 fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
939 } while (p_extra->eType != OMX_ExtraDataNone);
940 }
941 return 0;
942 }
943
venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)944 int venc_dev::venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
945 int size = 0;
946 if (!roiInfo || !m_debug.roiqp_log) {
947 DEBUG_PRINT_LOW("Nothing to log");
948 return 0;
949 }
950 if (!m_debug.roiqpfile) {
951 size = snprintf(m_debug.roiqpfile_name, PROPERTY_VALUE_MAX, "%s/enc_%lu_%lu_%p.roiqp",
952 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
953 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
954 DEBUG_PRINT_ERROR("Failed to open ROIQP file: %s for logging size:%d",
955 m_debug.roiqpfile_name, size);
956 m_debug.roiqpfile_name[0] = '\0';
957 return -1;
958 }
959 m_debug.roiqpfile = fopen(m_debug.roiqpfile_name, "ab");
960 if (!m_debug.roiqpfile) {
961 DEBUG_PRINT_ERROR("Failed to open ROI QP file: %s for logging errno:%d",
962 m_debug.roiqpfile_name, errno);
963 m_debug.roiqpfile_name[0] = '\0';
964 return -1;
965 }
966 }
967 if (m_debug.roiqpfile) {
968 if (fwrite(&mInputExtradata.mDbgEtbCount, sizeof(mInputExtradata.mDbgEtbCount), 1, m_debug.roiqpfile) != 1) {
969 DEBUG_PRINT_ERROR("Unable to write to QP file");
970 return -1;
971 }
972 if (fwrite(&roiInfo->nLowerQpOffset, sizeof(roiInfo->nLowerQpOffset), 1, m_debug.roiqpfile) != 1) {
973 DEBUG_PRINT_ERROR("Unable to write to QP file");
974 return -1;
975 }
976 if (fwrite(&roiInfo->nUpperQpOffset, sizeof(roiInfo->nUpperQpOffset), 1, m_debug.roiqpfile) != 1) {
977 DEBUG_PRINT_ERROR("Unable to write to QP file");
978 return -1;
979 }
980 if (fwrite((char *)roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize, 1, m_debug.roiqpfile) != 1) {
981 DEBUG_PRINT_ERROR("Unable to write to QP file");
982 return -1;
983 }
984 }
985 return 0;
986 }
987
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset,unsigned long inputformat)988 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset,
989 unsigned long inputformat) {
990 if (venc_handle->is_secure_session()) {
991 DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
992 return -1;
993 }
994
995 if (!m_debug.infile) {
996 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
997 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
998 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
999 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
1000 m_debug.infile_name, size);
1001 }
1002 m_debug.infile = fopen (m_debug.infile_name, "ab");
1003 if (!m_debug.infile) {
1004 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
1005 m_debug.infile_name[0] = '\0';
1006 return -1;
1007 }
1008 }
1009
1010 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
1011 int stride, scanlines;
1012 int color_format;
1013 unsigned long i, msize;
1014 unsigned char *pvirt = NULL, *ptemp = NULL;
1015 unsigned char *temp = (unsigned char *)pbuffer->pBuffer;
1016
1017 switch (inputformat) {
1018 case V4L2_PIX_FMT_NV12:
1019 color_format = COLOR_FMT_NV12;
1020 break;
1021 case V4L2_PIX_FMT_NV12_UBWC:
1022 color_format = COLOR_FMT_NV12_UBWC;
1023 break;
1024 case V4L2_PIX_FMT_RGB32:
1025 color_format = COLOR_FMT_RGBA8888;
1026 break;
1027 case V4L2_PIX_FMT_RGBA8888_UBWC:
1028 color_format = COLOR_FMT_RGBA8888_UBWC;
1029 break;
1030 default:
1031 color_format = COLOR_FMT_NV12;
1032 DEBUG_PRINT_LOW("Default format NV12 is set for logging [%lu]", inputformat);
1033 break;
1034 }
1035
1036 msize = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
1037 const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
1038
1039 if (metadatamode == 1) {
1040 pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
1041 if (pvirt == MAP_FAILED) {
1042 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
1043 return -1;
1044 }
1045 ptemp = pvirt;
1046 } else {
1047 ptemp = temp;
1048 }
1049
1050 if (color_format == COLOR_FMT_NV12) {
1051 stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
1052 scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
1053
1054 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1055 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1056 ptemp += stride;
1057 }
1058 if (metadatamode == 1) {
1059 ptemp = pvirt + (stride * scanlines);
1060 } else {
1061 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
1062 }
1063 for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
1064 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1065 ptemp += stride;
1066 }
1067 } else if (color_format == COLOR_FMT_RGBA8888) {
1068 stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width);
1069 scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height);
1070
1071 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1072 fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile);
1073 ptemp += stride;
1074 }
1075 } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) {
1076 if (color_format == COLOR_FMT_NV12_UBWC) {
1077 msize -= 2 * extra_size;
1078 }
1079 fwrite(ptemp, msize, 1, m_debug.infile);
1080 }
1081
1082 if (metadatamode == 1 && pvirt) {
1083 munmap(pvirt, msize);
1084 }
1085 }
1086
1087 return 0;
1088 }
1089
venc_open(OMX_U32 codec)1090 bool venc_dev::venc_open(OMX_U32 codec)
1091 {
1092 int r;
1093 unsigned int alignment = 0,buffer_size = 0, temp =0;
1094 struct v4l2_control control;
1095 OMX_STRING device_name = (OMX_STRING)"/dev/video33";
1096 char property_value[PROPERTY_VALUE_MAX] = {0};
1097 char platform_name[PROPERTY_VALUE_MAX] = {0};
1098 FILE *soc_file = NULL;
1099 char buffer[10];
1100
1101 property_get("ro.board.platform", platform_name, "0");
1102 property_get("vidc.enc.narrow.searchrange", property_value, "0");
1103 enable_mv_narrow_searchrange = atoi(property_value);
1104
1105 if (!strncmp(platform_name, "msm8610", 7)) {
1106 device_name = (OMX_STRING)"/dev/video/q6_enc";
1107 supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
1108 }
1109 m_nDriver_fd = open (device_name, O_RDWR);
1110 if ((int)m_nDriver_fd < 0) {
1111 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
1112 return false;
1113 }
1114 m_poll_efd = eventfd(0, 0);
1115 if (m_poll_efd < 0) {
1116 DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno));
1117 return false;
1118 }
1119 DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
1120
1121 // set the basic configuration of the video encoder driver
1122 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
1123 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
1124 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
1125 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
1126 m_sVenc_cfg.fps_num = 30;
1127 m_sVenc_cfg.fps_den = 1;
1128 m_sVenc_cfg.targetbitrate = 64000;
1129 m_sVenc_cfg.inputformat= V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1130
1131 m_codec = codec;
1132
1133 if (codec == OMX_VIDEO_CodingMPEG4) {
1134 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
1135 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
1136 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
1137 session_qp_range.minqp = 1;
1138 session_qp_range.maxqp = 31;
1139 } else if (codec == OMX_VIDEO_CodingH263) {
1140 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
1141 codec_profile.profile = VEN_PROFILE_H263_BASELINE;
1142 profile_level.level = VEN_LEVEL_H263_20;
1143 session_qp_range.minqp = 1;
1144 session_qp_range.maxqp = 31;
1145 } else if (codec == OMX_VIDEO_CodingAVC) {
1146 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
1147 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1148 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1149 session_qp_range.minqp = 1;
1150 session_qp_range.maxqp = 51;
1151 } else if (codec == OMX_VIDEO_CodingVP8) {
1152 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
1153 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
1154 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
1155 session_qp_range.minqp = 1;
1156 session_qp_range.maxqp = 128;
1157 } else if (codec == OMX_VIDEO_CodingHEVC) {
1158 m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
1159 session_qp_range.minqp = 1;
1160 session_qp_range.maxqp = 51;
1161 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
1162 profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
1163 }
1164 session_qp_values.minqp = session_qp_range.minqp;
1165 session_qp_values.maxqp = session_qp_range.maxqp;
1166
1167 int ret;
1168 ret = subscribe_to_events(m_nDriver_fd);
1169
1170 if (ret) {
1171 DEBUG_PRINT_ERROR("Subscribe Event Failed");
1172 return false;
1173 }
1174
1175 struct v4l2_fmtdesc fdesc;
1176 struct v4l2_format fmt;
1177 struct v4l2_requestbuffers bufreq;
1178 struct v4l2_capability cap;
1179
1180 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
1181
1182 if (ret) {
1183 DEBUG_PRINT_ERROR("Failed to query capabilities");
1184 } else {
1185 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1186 " version = %d, capabilities = %x", cap.driver, cap.card,
1187 cap.bus_info, cap.version, cap.capabilities);
1188 }
1189
1190 ret=0;
1191 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1192 fdesc.index=0;
1193
1194 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1195 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1196 fdesc.pixelformat, fdesc.flags);
1197 fdesc.index++;
1198 }
1199
1200 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1201 fdesc.index=0;
1202
1203 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1204 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1205 fdesc.pixelformat, fdesc.flags);
1206 fdesc.index++;
1207 }
1208
1209 is_thulium_v1 = false;
1210 soc_file= fopen("/sys/devices/soc0/soc_id", "r");
1211 if (soc_file) {
1212 fread(buffer, 1, 4, soc_file);
1213 fclose(soc_file);
1214 if (atoi(buffer) == 246) {
1215 soc_file = fopen("/sys/devices/soc0/revision", "r");
1216 if (soc_file) {
1217 fread(buffer, 1, 4, soc_file);
1218 fclose(soc_file);
1219 if (atoi(buffer) == 1) {
1220 is_thulium_v1 = true;
1221 DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
1222 }
1223 }
1224 }
1225 }
1226
1227 if (venc_handle->is_secure_session()) {
1228 m_sOutput_buff_property.alignment = SZ_1M;
1229 m_sInput_buff_property.alignment = SZ_1M;
1230 } else {
1231 m_sOutput_buff_property.alignment = SZ_4K;
1232 m_sInput_buff_property.alignment = SZ_4K;
1233 }
1234
1235 memset(&fmt, 0, sizeof(fmt));
1236 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1237 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1238 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1239 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1240
1241 /*TODO: Return values not handled properly in this function anywhere.
1242 * Need to handle those.*/
1243 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1244
1245 if (ret) {
1246 DEBUG_PRINT_ERROR("Failed to set format on capture port");
1247 return false;
1248 }
1249
1250 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1251
1252 memset(&fmt, 0, sizeof(fmt));
1253 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1254 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1255 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1256 fmt.fmt.pix_mp.pixelformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1257 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1258
1259 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1260 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1261
1262 bufreq.memory = V4L2_MEMORY_USERPTR;
1263 bufreq.count = 2;
1264
1265 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1266 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1267 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1268
1269 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1270 bufreq.count = 2;
1271 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1272 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1273
1274 if(venc_handle->is_secure_session()) {
1275 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1276 control.value = 1;
1277 DEBUG_PRINT_HIGH("ioctl: open secure device");
1278 ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
1279 if (ret) {
1280 DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
1281 return false;
1282 }
1283 }
1284
1285 resume_in_stopped = 0;
1286 metadatamode = 0;
1287
1288 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
1289 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
1290
1291 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
1292
1293 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1294 DEBUG_PRINT_ERROR("Failed to set control");
1295
1296 struct v4l2_frmsizeenum frmsize;
1297
1298 //Get the hardware capabilities
1299 memset((void *)&frmsize,0,sizeof(frmsize));
1300 frmsize.index = 0;
1301 frmsize.pixel_format = m_sVenc_cfg.codectype;
1302 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1303
1304 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1305 DEBUG_PRINT_ERROR("Failed to get framesizes");
1306 return false;
1307 }
1308
1309 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1310 capability.min_width = frmsize.stepwise.min_width;
1311 capability.max_width = frmsize.stepwise.max_width;
1312 capability.min_height = frmsize.stepwise.min_height;
1313 capability.max_height = frmsize.stepwise.max_height;
1314 }
1315
1316 //Initialize non-default parameters
1317 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1318 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
1319 control.value = 0x7fffffff;
1320 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1321 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
1322 }
1323
1324 property_get("vidc.debug.turbo", property_value, "0");
1325 if (atoi(property_value)) {
1326 DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
1327 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
1328 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
1329 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1330 DEBUG_PRINT_ERROR("Failed to set turbo mode");
1331 }
1332 }
1333 return true;
1334 }
1335
1336
unsubscribe_to_events(int fd)1337 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
1338 {
1339 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1340 struct v4l2_event_subscription sub;
1341 int array_sz = sizeof(event_type)/sizeof(int);
1342 int i,rc;
1343
1344 if (fd < 0) {
1345 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1346 return OMX_ErrorBadParameter;
1347 }
1348
1349 for (i = 0; i < array_sz; ++i) {
1350 memset(&sub, 0, sizeof(sub));
1351 sub.type = event_type[i];
1352 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1353
1354 if (rc) {
1355 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1356 break;
1357 }
1358 }
1359
1360 return eRet;
1361 }
1362
venc_close()1363 void venc_dev::venc_close()
1364 {
1365 DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
1366
1367 if ((int)m_nDriver_fd >= 0) {
1368 DEBUG_PRINT_HIGH("venc_close E");
1369
1370 if(eventfd_write(m_poll_efd, 1)) {
1371 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1372 async_thread_force_stop = true;
1373 }
1374
1375 if (async_thread_created)
1376 pthread_join(m_tid,NULL);
1377
1378 DEBUG_PRINT_HIGH("venc_close X");
1379 unsubscribe_to_events(m_nDriver_fd);
1380 close(m_poll_efd);
1381 close(m_nDriver_fd);
1382 m_nDriver_fd = -1;
1383 }
1384
1385 if (m_debug.infile) {
1386 fclose(m_debug.infile);
1387 m_debug.infile = NULL;
1388 }
1389
1390 if (m_debug.outfile) {
1391 fclose(m_debug.outfile);
1392 m_debug.outfile = NULL;
1393 }
1394
1395 if (m_debug.extradatafile) {
1396 fclose(m_debug.extradatafile);
1397 m_debug.extradatafile = NULL;
1398 }
1399
1400 if (m_debug.roiqpfile) {
1401 fclose(m_debug.roiqpfile);
1402 m_debug.roiqpfile = NULL;
1403 }
1404 }
1405
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1406 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1407 OMX_U32 *actual_buff_count,
1408 OMX_U32 *buff_size,
1409 OMX_U32 port)
1410 {
1411 (void)min_buff_count, (void)buff_size;
1412 unsigned long temp_count = 0;
1413
1414 if (port == 0) {
1415 if (*actual_buff_count > m_sInput_buff_property.mincount) {
1416 temp_count = m_sInput_buff_property.actualcount;
1417 m_sInput_buff_property.actualcount = *actual_buff_count;
1418 DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1419 }
1420 } else {
1421 if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1422 temp_count = m_sOutput_buff_property.actualcount;
1423 m_sOutput_buff_property.actualcount = *actual_buff_count;
1424 DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1425 }
1426 }
1427
1428 return true;
1429
1430 }
1431
venc_loaded_start()1432 bool venc_dev::venc_loaded_start()
1433 {
1434 return true;
1435 }
1436
venc_loaded_stop()1437 bool venc_dev::venc_loaded_stop()
1438 {
1439 return true;
1440 }
1441
venc_loaded_start_done()1442 bool venc_dev::venc_loaded_start_done()
1443 {
1444 return true;
1445 }
1446
venc_loaded_stop_done()1447 bool venc_dev::venc_loaded_stop_done()
1448 {
1449 return true;
1450 }
1451
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)1452 bool venc_dev::venc_get_seq_hdr(void *buffer,
1453 unsigned buffer_size, unsigned *header_len)
1454 {
1455 (void) buffer, (void) buffer_size, (void) header_len;
1456 return true;
1457 }
1458
venc_get_dimensions(OMX_U32 portIndex,OMX_U32 * w,OMX_U32 * h)1459 bool venc_dev::venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h) {
1460 struct v4l2_format fmt;
1461 memset(&fmt, 0, sizeof(fmt));
1462 fmt.type = portIndex == PORT_INDEX_OUT ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
1463 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1464
1465 if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
1466 DEBUG_PRINT_ERROR("Failed to get format on %s port",
1467 portIndex == PORT_INDEX_OUT ? "capture" : "output");
1468 return false;
1469 }
1470 *w = fmt.fmt.pix_mp.width;
1471 *h = fmt.fmt.pix_mp.height;
1472 return true;
1473 }
1474
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1475 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1476 OMX_U32 *actual_buff_count,
1477 OMX_U32 *buff_size,
1478 OMX_U32 port)
1479 {
1480 struct v4l2_format fmt;
1481 struct v4l2_requestbuffers bufreq;
1482 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1483 int ret;
1484 int extra_idx = 0;
1485
1486 if (port == 0) {
1487 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1488 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1489 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1490 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1491 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1492 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1493 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1494 bufreq.memory = V4L2_MEMORY_USERPTR;
1495
1496 if (*actual_buff_count)
1497 bufreq.count = *actual_buff_count;
1498 else
1499 bufreq.count = 2;
1500
1501 // Increase buffer-header count for metadata-mode on input port
1502 // to improve buffering and reduce bottlenecks in clients
1503 if (metadatamode && (bufreq.count < 9)) {
1504 DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
1505 bufreq.count);
1506 bufreq.count = 9;
1507 }
1508 if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
1509 DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
1510 bufreq.count = 11;
1511 }
1512
1513 int actualCount = bufreq.count;
1514 // Request MAX_V4L2_BUFS from V4L2 in batch mode.
1515 // Keep the original count for the client
1516 if (metadatamode && mBatchSize) {
1517 bufreq.count = MAX_V4L2_BUFS;
1518 }
1519
1520 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1521 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1522
1523 if (ret) {
1524 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1525 return false;
1526 }
1527 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1528 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1529 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1530 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1531 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1532 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1533
1534 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = actualCount;
1535 *min_buff_count = m_sInput_buff_property.mincount;
1536 *actual_buff_count = m_sInput_buff_property.actualcount;
1537 #ifdef USE_ION
1538 // For ION memory allocations of the allocated buffer size
1539 // must be 4k aligned, hence aligning the input buffer
1540 // size to 4k.
1541 m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1542 #endif
1543 *buff_size = m_sInput_buff_property.datasize;
1544 num_input_planes = fmt.fmt.pix_mp.num_planes;
1545 extra_idx = EXTRADATA_IDX(num_input_planes);
1546
1547 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1548 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1549 } else if (extra_idx >= VIDEO_MAX_PLANES) {
1550 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
1551 return OMX_ErrorBadParameter;
1552 }
1553 mInputExtradata.update(m_sInput_buff_property.actualcount + 1, extra_data_size);
1554 } else {
1555 unsigned int extra_idx = 0;
1556 memset(&fmt, 0, sizeof(fmt));
1557 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1558 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1559 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1560 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1561
1562 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1563 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1564 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1565 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1566 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1567 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1568
1569 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1570 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1571 bufreq.memory = V4L2_MEMORY_USERPTR;
1572
1573 if (mBatchSize) {
1574 // If we're in batch mode, we'd like to end up in a situation where
1575 // driver is able to own mBatchSize buffers and we'd also own atleast
1576 // mBatchSize buffers
1577 bufreq.count = MAX(*actual_buff_count, mBatchSize) + mBatchSize;
1578 } else if (*actual_buff_count) {
1579 bufreq.count = *actual_buff_count;
1580 } else {
1581 bufreq.count = 2;
1582 }
1583
1584 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1585 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1586
1587 if (ret) {
1588 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1589 return false;
1590 }
1591
1592 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1593 *min_buff_count = m_sOutput_buff_property.mincount;
1594 *actual_buff_count = m_sOutput_buff_property.actualcount;
1595 *buff_size = m_sOutput_buff_property.datasize;
1596 num_output_planes = fmt.fmt.pix_mp.num_planes;
1597 extra_idx = EXTRADATA_IDX(num_output_planes);
1598
1599 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1600 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1601 } else if (extra_idx >= VIDEO_MAX_PLANES) {
1602 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1603 return OMX_ErrorBadParameter;
1604 }
1605 mOutputExtradata.update(m_sOutput_buff_property.actualcount, extra_data_size);
1606 }
1607
1608 return true;
1609 }
1610
venc_set_param(void * paramData,OMX_INDEXTYPE index)1611 bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index)
1612 {
1613 DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1614 struct v4l2_format fmt;
1615 struct v4l2_requestbuffers bufreq;
1616 int ret;
1617
1618 switch ((int)index) {
1619 case OMX_IndexParamPortDefinition:
1620 {
1621 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1622 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1623 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1624
1625 if (portDefn->nPortIndex == PORT_INDEX_IN) {
1626 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1627 return false;
1628 }
1629
1630 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1631 return false;
1632 }
1633 if (enable_mv_narrow_searchrange &&
1634 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1635 (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1636 if (venc_set_searchrange() == false) {
1637 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1638 }
1639 }
1640 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1641 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1642 DEBUG_PRINT_LOW("Basic parameter has changed");
1643 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1644 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1645
1646 memset(&fmt, 0, sizeof(fmt));
1647 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1648 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1649 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1650 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1651 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1652
1653 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1654 DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1655 hw_overload = errno == EBUSY;
1656 return false;
1657 }
1658
1659 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1660 bufreq.memory = V4L2_MEMORY_USERPTR;
1661 bufreq.count = portDefn->nBufferCountActual;
1662 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1663
1664 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1665 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1666 return false;
1667 }
1668
1669 if (bufreq.count == portDefn->nBufferCountActual)
1670 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1671
1672 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1673 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1674 }
1675
1676 DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1677 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1678 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1679 m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1680 m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1681
1682 memset(&fmt, 0, sizeof(fmt));
1683 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1684 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1685 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1686 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1687
1688 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1689 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1690 hw_overload = errno == EBUSY;
1691 return false;
1692 }
1693
1694 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1695
1696 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1697 return false;
1698 }
1699
1700 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1701 bufreq.memory = V4L2_MEMORY_USERPTR;
1702 bufreq.count = portDefn->nBufferCountActual;
1703 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1704
1705 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1706 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1707 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1708 return false;
1709 }
1710
1711 if (bufreq.count == portDefn->nBufferCountActual)
1712 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1713
1714 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1715 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1716
1717 DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1718 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1719 } else {
1720 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1721 }
1722
1723 break;
1724 }
1725 case OMX_IndexParamVideoPortFormat:
1726 {
1727 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1728 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1729 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1730
1731 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1732 if (!venc_set_color_format(portFmt->eColorFormat)) {
1733 return false;
1734 }
1735 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1736 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1737 return false;
1738 }
1739 } else {
1740 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1741 }
1742
1743 break;
1744 }
1745 case OMX_IndexParamVideoBitrate:
1746 {
1747 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1748 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1749 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1750
1751 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1752 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1753 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1754 return false;
1755 }
1756
1757 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1758 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1759 return false;
1760 }
1761 } else {
1762 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1763 }
1764
1765 break;
1766 }
1767 case OMX_IndexParamVideoMpeg4:
1768 {
1769 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1770 OMX_U32 bFrames = 0;
1771
1772 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1773 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1774
1775 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1776 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1777 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1778 return false;
1779 }
1780
1781 m_profile_set = false;
1782 m_level_set = false;
1783 rc_off_level = (int)pParam->eLevel;
1784 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1785 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1786 return false;
1787 } else {
1788 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1789 if (pParam->nBFrames) {
1790 bFrames = pParam->nBFrames;
1791 }
1792 } else {
1793 if (pParam->nBFrames) {
1794 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1795 bFrames = 0;
1796 }
1797 }
1798 }
1799
1800 if (!venc_set_intra_period_config (pParam->nPFrames,bFrames)) {
1801 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1802 return false;
1803 }
1804
1805 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1806 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1807 return false;
1808 }
1809 } else {
1810 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1811 }
1812
1813 break;
1814 }
1815 case OMX_IndexParamVideoH263:
1816 {
1817 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1818 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1819 OMX_U32 bFrames = 0;
1820
1821 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1822 m_profile_set = false;
1823 m_level_set = false;
1824 rc_off_level = (int)pParam->eLevel;
1825 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1826 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1827 return false;
1828 }
1829
1830 if (pParam->nBFrames)
1831 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1832
1833 if (venc_set_intra_period_config (pParam->nPFrames, bFrames) == false) {
1834 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1835 return false;
1836 }
1837 } else {
1838 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1839 }
1840
1841 break;
1842 }
1843 case OMX_IndexParamVideoAvc:
1844 {
1845 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1846 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1847 OMX_U32 bFrames = 0;
1848
1849 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1850 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1851 pParam->eProfile,pParam->eLevel);
1852
1853 m_profile_set = false;
1854 m_level_set = false;
1855 rc_off_level = (int)pParam->eLevel;
1856 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1857 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1858 pParam->eProfile, pParam->eLevel);
1859 return false;
1860 } else {
1861 if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1862 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1863 if (pParam->nBFrames) {
1864 bFrames = pParam->nBFrames;
1865 }
1866 } else {
1867 if (pParam->nBFrames) {
1868 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1869 bFrames = 0;
1870 }
1871 }
1872 }
1873
1874 if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) {
1875 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1876 return false;
1877 }
1878
1879 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1880 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1881 return false;
1882 }
1883
1884 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1885 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1886 return false;
1887 }
1888
1889 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1890 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1891 return false;
1892 }
1893 } else {
1894 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1895 }
1896
1897 //TBD, lot of other variables to be updated, yet to decide
1898 break;
1899 }
1900 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1901 {
1902 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1903 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1904 rc_off_level = (int)pParam->eLevel;
1905 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1906 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1907 pParam->eProfile, pParam->eLevel);
1908 return false;
1909 }
1910 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1911 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1912 return false;
1913 }
1914 if(!venc_set_ltrmode(1, 1)) {
1915 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1916 return false;
1917 }
1918
1919 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1920 // Disable hier-p if ltr is enabled.
1921 if (m_codec == OMX_VIDEO_CodingVP8) {
1922 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1923 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1924 DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1925 }
1926 }
1927
1928 break;
1929 }
1930 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1931 {
1932 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1933 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1934 rc_off_level = (int)pParam->eLevel;
1935 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1936 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1937 pParam->eProfile, pParam->eLevel);
1938 return false;
1939 }
1940 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1941 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1942
1943 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1944 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1945 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1946 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1947 return false;
1948 }
1949 break;
1950 }
1951 case OMX_IndexParamVideoIntraRefresh:
1952 {
1953 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1954 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1955 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1956
1957 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1958 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1959 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1960 return false;
1961 }
1962 } else {
1963 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1964 }
1965
1966 break;
1967 }
1968 case OMX_IndexParamVideoErrorCorrection:
1969 {
1970 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1971 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1972 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1973
1974 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1975 if (venc_set_error_resilience(error_resilience) == false) {
1976 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1977 return false;
1978 }
1979 } else {
1980 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1981 }
1982
1983 break;
1984 }
1985 case OMX_IndexParamVideoProfileLevelCurrent:
1986 {
1987 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1988 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1989 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1990
1991 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1992 m_profile_set = false;
1993 m_level_set = false;
1994 rc_off_level = (int)profile_level->eLevel;
1995 if (!venc_set_profile_level (profile_level->eProfile,
1996 profile_level->eLevel)) {
1997 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1998 return false;
1999 }
2000 } else {
2001 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
2002 }
2003
2004 break;
2005 }
2006 case OMX_IndexParamVideoQuantization:
2007 {
2008 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
2009 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
2010 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
2011 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2012 if (venc_set_session_qp (session_qp->nQpI,
2013 session_qp->nQpP,
2014 session_qp->nQpB) == false) {
2015 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
2016 return false;
2017 }
2018 } else {
2019 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
2020 }
2021
2022 break;
2023 }
2024 case QOMX_IndexParamVideoInitialQp:
2025 {
2026 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
2027 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
2028 if (initqp->bEnableInitQp) {
2029 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
2030 if(venc_enable_initial_qp(initqp) == false) {
2031 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
2032 return OMX_ErrorUnsupportedSetting;
2033 }
2034 } else
2035 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
2036 break;
2037 }
2038 case OMX_QcomIndexParamVideoQPRange:
2039 {
2040 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
2041 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
2042 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
2043
2044 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2045 if(venc_set_session_qp_range (session_qp_range->minQP,
2046 session_qp_range->maxQP) == false) {
2047 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
2048 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
2049 return false;
2050 } else {
2051 session_qp_values.minqp = session_qp_range->minQP;
2052 session_qp_values.maxqp = session_qp_range->maxQP;
2053 }
2054 } else {
2055 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
2056 }
2057
2058 break;
2059 }
2060 case OMX_QcomIndexEnableSliceDeliveryMode:
2061 {
2062 QOMX_EXTNINDEX_PARAMTYPE* pParam =
2063 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
2064
2065 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2066 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
2067 DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
2068 return OMX_ErrorUnsupportedSetting;
2069 }
2070 } else {
2071 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
2072 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
2073 return OMX_ErrorBadPortIndex;
2074 }
2075
2076 break;
2077 }
2078 case OMX_ExtraDataFrameDimension:
2079 {
2080 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
2081 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2082
2083 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
2084 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
2085 return false;
2086 }
2087
2088 extradata = true;
2089 break;
2090 }
2091 case OMX_ExtraDataVideoEncoderSliceInfo:
2092 {
2093 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
2094 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2095
2096 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
2097 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
2098 return false;
2099 }
2100
2101 extradata = true;
2102 break;
2103 }
2104 case OMX_ExtraDataVideoEncoderMBInfo:
2105 {
2106 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
2107 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2108
2109 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
2110 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
2111 return false;
2112 }
2113
2114 extradata = true;
2115 break;
2116 }
2117 case OMX_QcomIndexParamSequenceHeaderWithIDR:
2118 {
2119 PrependSPSPPSToIDRFramesParams * pParam =
2120 (PrependSPSPPSToIDRFramesParams *)paramData;
2121
2122 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
2123 if(venc_set_inband_video_header(pParam->bEnable) == false) {
2124 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
2125 return OMX_ErrorUnsupportedSetting;
2126 }
2127
2128 break;
2129 }
2130 case OMX_QcomIndexParamH264AUDelimiter:
2131 {
2132 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
2133 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
2134
2135 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
2136 if(venc_set_au_delimiter(pParam->bEnable) == false) {
2137 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
2138 return OMX_ErrorUnsupportedSetting;
2139 }
2140
2141 break;
2142 }
2143 case OMX_QcomIndexParamMBIStatisticsMode:
2144 {
2145 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
2146 (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
2147
2148 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
2149 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
2150 DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
2151 return OMX_ErrorUnsupportedSetting;
2152 }
2153
2154 break;
2155 }
2156
2157 case OMX_QcomIndexConfigH264EntropyCodingCabac:
2158 {
2159 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
2160 (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
2161
2162 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
2163 if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
2164 DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
2165 return OMX_ErrorUnsupportedSetting;
2166 }
2167
2168 break;
2169 }
2170
2171 case OMX_QcomIndexHierarchicalStructure:
2172 {
2173 QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
2174 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
2175
2176 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2177 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
2178 DEBUG_PRINT_ERROR("Setting Hier P count failed");
2179 return false;
2180 }
2181 } else {
2182 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
2183 return false;
2184 }
2185
2186 // For VP8, hier-p and ltr are mutually exclusive features in firmware
2187 // Disable ltr if hier-p is enabled.
2188 if (m_codec == OMX_VIDEO_CodingVP8) {
2189 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
2190 if(!venc_set_ltrmode(0, 1)) {
2191 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
2192 }
2193 }
2194 break;
2195 }
2196 case OMX_QcomIndexParamPerfLevel:
2197 {
2198 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
2199 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
2200 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
2201 if (!venc_set_perf_level(pParam->ePerfLevel)) {
2202 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
2203 return false;
2204 } else {
2205 performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
2206 }
2207 break;
2208 }
2209 case OMX_QcomIndexParamH264VUITimingInfo:
2210 {
2211 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
2212 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
2213 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
2214 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
2215 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
2216 return false;
2217 } else {
2218 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
2219 }
2220 break;
2221 }
2222 case OMX_QTIIndexParamVQZIPSEIType:
2223 {
2224 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
2225 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
2226 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
2227 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
2228 DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
2229 return false;
2230 }
2231 break;
2232 }
2233 case OMX_QcomIndexParamPeakBitrate:
2234 {
2235 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
2236 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
2237 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
2238 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
2239 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
2240 return false;
2241 } else {
2242 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
2243 }
2244 break;
2245 }
2246 case OMX_QcomIndexParamSetMVSearchrange:
2247 {
2248 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
2249 is_searchrange_set = true;
2250 if (!venc_set_searchrange()) {
2251 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
2252 return false;
2253 }
2254 }
2255 break;
2256 case OMX_QcomIndexParamVideoLTRCount:
2257 {
2258 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
2259 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
2260 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
2261 if (pParam->nCount > 0) {
2262 if (venc_set_ltrmode(1, pParam->nCount) == false) {
2263 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
2264 return false;
2265 }
2266 } else {
2267 if (venc_set_ltrmode(0, 0) == false) {
2268 DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
2269 return false;
2270 }
2271 }
2272 break;
2273 }
2274 case OMX_QcomIndexParamVideoHybridHierpMode:
2275 {
2276 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
2277 DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
2278 return false;
2279 }
2280 break;
2281 }
2282 case OMX_QcomIndexParamBatchSize:
2283 {
2284 OMX_PARAM_U32TYPE* pParam =
2285 (OMX_PARAM_U32TYPE*)paramData;
2286
2287 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2288 DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
2289 " on output port");
2290 return OMX_ErrorUnsupportedSetting;
2291 }
2292
2293 if (!venc_set_batch_size(pParam->nU32)) {
2294 DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
2295 return OMX_ErrorUnsupportedSetting;
2296 }
2297 break;
2298 }
2299 case OMX_QcomIndexParamVencAspectRatio:
2300 {
2301 if (!venc_set_aspectratio(paramData)) {
2302 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
2303 return OMX_ErrorUnsupportedSetting;
2304 }
2305 break;
2306 }
2307 case OMX_QTIIndexParamVideoEnableRoiInfo:
2308 {
2309 struct v4l2_control control;
2310 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
2311 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
2312 DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
2313 return OMX_ErrorUnsupportedSetting;
2314 }
2315 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2316 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
2317 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
2318 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2319 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
2320 return OMX_ErrorUnsupportedSetting;
2321 }
2322 break;
2323 }
2324 case OMX_IndexParamAndroidVideoTemporalLayering:
2325 {
2326 if (venc_set_temporal_layers(
2327 (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
2328 DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
2329 return false;
2330 }
2331 break;
2332 }
2333 case OMX_QTIIndexParamEnableAVTimerTimestamps:
2334 {
2335 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
2336 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
2337 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
2338 break;
2339 }
2340 case OMX_IndexParamVideoSliceFMO:
2341 default:
2342 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
2343 index);
2344 break;
2345 //case
2346 }
2347
2348 return true;
2349 }
2350
venc_check_valid_config()2351 bool venc_dev::venc_check_valid_config()
2352 {
2353 if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
2354 ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
2355 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
2356 DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
2357 DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
2358 DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
2359 return false;
2360 }
2361 return true;
2362 }
2363
venc_set_config(void * configData,OMX_INDEXTYPE index)2364 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
2365 {
2366
2367 DEBUG_PRINT_LOW("Inside venc_set_config");
2368
2369 if(!venc_check_valid_config()) {
2370 DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
2371 return false;
2372 }
2373
2374 switch ((int)index) {
2375 case OMX_IndexConfigVideoBitrate:
2376 {
2377 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
2378 configData;
2379 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
2380
2381 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2382 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
2383 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
2384 return false;
2385 }
2386 } else {
2387 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
2388 }
2389
2390 break;
2391 }
2392 case OMX_IndexConfigVideoFramerate:
2393 {
2394 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
2395 configData;
2396 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
2397
2398 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2399 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
2400 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2401 return false;
2402 }
2403 } else {
2404 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2405 }
2406
2407 break;
2408 }
2409 case QOMX_IndexConfigVideoIntraperiod:
2410 {
2411 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
2412 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
2413 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
2414
2415 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2416 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
2417 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
2418 return false;
2419 }
2420 }
2421
2422 break;
2423 }
2424 case OMX_IndexConfigVideoIntraVOPRefresh:
2425 {
2426 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
2427 configData;
2428 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
2429
2430 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2431 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2432 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2433 return false;
2434 }
2435 } else {
2436 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2437 }
2438
2439 break;
2440 }
2441 case OMX_IndexConfigCommonRotate:
2442 {
2443 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2444 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2445 OMX_U32 nFrameWidth;
2446 if (!config_rotation) {
2447 return false;
2448 }
2449 if (true == deinterlace_enabled) {
2450 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2451 return false;
2452 }
2453 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2454 nFrameWidth = m_sVenc_cfg.dvs_width;
2455 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height;
2456 m_sVenc_cfg.dvs_height = nFrameWidth;
2457
2458 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2459 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2460 return false;
2461 }
2462
2463 break;
2464 }
2465 case OMX_IndexConfigVideoAVCIntraPeriod:
2466 {
2467 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2468 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2469
2470 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2471 == false) {
2472 DEBUG_PRINT_ERROR("ERROR: Setting "
2473 "OMX_IndexConfigVideoAVCIntraPeriod failed");
2474 return false;
2475 }
2476 break;
2477 }
2478 case OMX_IndexConfigCommonDeinterlace:
2479 {
2480 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2481 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2482 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2483 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2484 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2485 {
2486 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2487 return false;
2488 }
2489 if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2490 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2491 return false;
2492 }
2493 } else {
2494 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2495 }
2496 break;
2497 }
2498 case OMX_IndexConfigVideoVp8ReferenceFrame:
2499 {
2500 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2501 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2502 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2503 (vp8refframe->bUseGoldenFrame)) {
2504 if(venc_set_useltr(0x1) == false) {
2505 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2506 return false;
2507 }
2508 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2509 (vp8refframe->bGoldenFrameRefresh)) {
2510 if(venc_set_markltr(0x1) == false) {
2511 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2512 return false;
2513 }
2514 } else {
2515 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2516 }
2517 break;
2518 }
2519 case OMX_QcomIndexConfigVideoLTRUse:
2520 {
2521 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2522 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2523 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2524 if (venc_set_useltr(pParam->nID) == false) {
2525 DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2526 return false;
2527 }
2528 } else {
2529 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2530 }
2531 break;
2532 }
2533 case OMX_QcomIndexConfigVideoLTRMark:
2534 {
2535 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2536 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2537 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2538 if (venc_set_markltr(pParam->nID) == false) {
2539 DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2540 return false;
2541 }
2542 } else {
2543 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2544 }
2545 break;
2546 }
2547 case OMX_QcomIndexConfigPerfLevel:
2548 {
2549 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2550 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2551 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2552 if (!venc_set_perf_level(perf->ePerfLevel)) {
2553 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2554 return false;
2555 } else {
2556 performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2557 }
2558 break;
2559 }
2560 case OMX_QcomIndexConfigVideoVencPerfMode:
2561 {
2562 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2563 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2564 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2565 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2566 return false;
2567 }
2568 break;
2569 }
2570 case OMX_QcomIndexConfigNumHierPLayers:
2571 {
2572 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
2573 (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
2574 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
2575 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
2576 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
2577 return false;
2578 }
2579 break;
2580 }
2581 case OMX_QcomIndexConfigBaseLayerId:
2582 {
2583 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
2584 (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
2585 if (venc_set_baselayerid(pParam->nPID) == false) {
2586 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
2587 return OMX_ErrorUnsupportedSetting;
2588 }
2589 break;
2590 }
2591 case OMX_IndexParamAndroidVideoTemporalLayering:
2592 {
2593 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2594 return false;
2595 }
2596 case OMX_QcomIndexConfigQp:
2597 {
2598 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
2599 (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
2600 if (venc_set_qp(pParam->nQP) == false) {
2601 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
2602 return OMX_ErrorUnsupportedSetting;
2603 }
2604 break;
2605 }
2606 case OMX_IndexConfigPriority:
2607 {
2608 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2609 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
2610 if (!venc_set_priority(priority->nU32)) {
2611 DEBUG_PRINT_ERROR("Failed to set priority");
2612 return false;
2613 }
2614 sess_priority.priority = priority->nU32;
2615 break;
2616 }
2617 case OMX_IndexConfigOperatingRate:
2618 {
2619 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2620 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2621 if (!venc_set_operatingrate(rate->nU32)) {
2622 DEBUG_PRINT_ERROR("Failed to set operating rate");
2623 return false;
2624 }
2625 break;
2626 }
2627 case OMX_QTIIndexConfigVideoRoiInfo:
2628 {
2629 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
2630 DEBUG_PRINT_ERROR("Failed to set ROI QP info");
2631 return false;
2632 }
2633 break;
2634 }
2635 case OMX_IndexConfigAndroidIntraRefresh:
2636 {
2637 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2638 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2639
2640 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2641 OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2642 OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2643
2644 if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2645 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2646 return false;
2647 }
2648 } else {
2649 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2650 }
2651 break;
2652 }
2653 case OMX_QTIIndexConfigDescribeColorAspects:
2654 {
2655 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
2656
2657 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
2658 OMX_U32 full_range = 0;
2659 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2660 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2661
2662 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
2663 case ColorAspects::PrimariesBT709_5:
2664 color_space = MSM_VIDC_BT709_5;
2665 break;
2666 case ColorAspects::PrimariesBT470_6M:
2667 color_space = MSM_VIDC_BT470_6_M;
2668 break;
2669 case ColorAspects::PrimariesBT601_6_625:
2670 color_space = MSM_VIDC_BT601_6_625;
2671 break;
2672 case ColorAspects::PrimariesBT601_6_525:
2673 color_space = MSM_VIDC_BT601_6_525;
2674 break;
2675 case ColorAspects::PrimariesGenericFilm:
2676 color_space = MSM_VIDC_GENERIC_FILM;
2677 break;
2678 case ColorAspects::PrimariesBT2020:
2679 color_space = MSM_VIDC_BT2020;
2680 break;
2681 default:
2682 color_space = MSM_VIDC_BT601_6_625;
2683 //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2684 break;
2685 }
2686 switch((ColorAspects::Range)params->sAspects.mRange) {
2687 case ColorAspects::RangeFull:
2688 full_range = 1;
2689 break;
2690 case ColorAspects::RangeLimited:
2691 full_range = 0;
2692 break;
2693 default:
2694 break;
2695 }
2696 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
2697 case ColorAspects::TransferSMPTE170M:
2698 transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
2699 break;
2700 case ColorAspects::TransferUnspecified:
2701 transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
2702 break;
2703 case ColorAspects::TransferGamma22:
2704 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
2705 break;
2706 case ColorAspects::TransferGamma28:
2707 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
2708 break;
2709 case ColorAspects::TransferSMPTE240M:
2710 transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
2711 break;
2712 case ColorAspects::TransferLinear:
2713 transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
2714 break;
2715 case ColorAspects::TransferXvYCC:
2716 transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
2717 break;
2718 case ColorAspects::TransferBT1361:
2719 transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
2720 break;
2721 case ColorAspects::TransferSRGB:
2722 transfer_chars = MSM_VIDC_TRANSFER_SRGB;
2723 break;
2724 default:
2725 //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2726 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2727 break;
2728 }
2729 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
2730 case ColorAspects::MatrixUnspecified:
2731 matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
2732 break;
2733 case ColorAspects::MatrixBT709_5:
2734 matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
2735 break;
2736 case ColorAspects::MatrixBT470_6M:
2737 matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
2738 break;
2739 case ColorAspects::MatrixBT601_6:
2740 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
2741 break;
2742 case ColorAspects::MatrixSMPTE240M:
2743 transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
2744 break;
2745 case ColorAspects::MatrixBT2020:
2746 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
2747 break;
2748 case ColorAspects::MatrixBT2020Constant:
2749 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
2750 break;
2751 default:
2752 //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2753 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2754 break;
2755 }
2756 if (!venc_set_colorspace(color_space, full_range,
2757 transfer_chars, matrix_coeffs)) {
2758
2759 DEBUG_PRINT_ERROR("Failed to set operating rate");
2760 return false;
2761 }
2762 break;
2763 }
2764 default:
2765 DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2766 break;
2767 }
2768
2769 return true;
2770 }
2771
venc_stop(void)2772 unsigned venc_dev::venc_stop( void)
2773 {
2774 struct venc_msg venc_msg;
2775 struct v4l2_requestbuffers bufreq;
2776 int rc = 0, ret = 0;
2777
2778 if (!stopped) {
2779 enum v4l2_buf_type cap_type;
2780
2781 if (streaming[OUTPUT_PORT]) {
2782 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2783 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2784
2785 if (rc) {
2786 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2787 cap_type, rc);
2788 } else
2789 streaming[OUTPUT_PORT] = false;
2790
2791 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2792 bufreq.memory = V4L2_MEMORY_USERPTR;
2793 bufreq.count = 0;
2794 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2795 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2796
2797 if (ret) {
2798 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2799 return false;
2800 }
2801 }
2802
2803 if (!rc && streaming[CAPTURE_PORT]) {
2804 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2805 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2806
2807 if (rc) {
2808 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2809 cap_type, rc);
2810 } else
2811 streaming[CAPTURE_PORT] = false;
2812
2813 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2814 bufreq.memory = V4L2_MEMORY_USERPTR;
2815 bufreq.count = 0;
2816 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2817 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2818
2819 if (ret) {
2820 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2821 return false;
2822 }
2823 }
2824
2825 if (!rc && !ret) {
2826 venc_stop_done();
2827 stopped = 1;
2828 /*set flag to re-configure when started again*/
2829 resume_in_stopped = 1;
2830
2831 }
2832 }
2833
2834 return rc;
2835 }
2836
venc_pause(void)2837 unsigned venc_dev::venc_pause(void)
2838 {
2839 pthread_mutex_lock(&pause_resume_mlock);
2840 paused = true;
2841 pthread_mutex_unlock(&pause_resume_mlock);
2842 return 0;
2843 }
2844
venc_resume(void)2845 unsigned venc_dev::venc_resume(void)
2846 {
2847 pthread_mutex_lock(&pause_resume_mlock);
2848 paused = false;
2849 pthread_mutex_unlock(&pause_resume_mlock);
2850
2851 return pthread_cond_signal(&pause_resume_cond);
2852 }
2853
venc_start_done(void)2854 unsigned venc_dev::venc_start_done(void)
2855 {
2856 struct venc_msg venc_msg;
2857 venc_msg.msgcode = VEN_MSG_START;
2858 venc_msg.statuscode = VEN_S_SUCCESS;
2859 venc_handle->async_message_process(venc_handle,&venc_msg);
2860 return 0;
2861 }
2862
venc_stop_done(void)2863 unsigned venc_dev::venc_stop_done(void)
2864 {
2865 struct venc_msg venc_msg;
2866 venc_msg.msgcode=VEN_MSG_STOP;
2867 venc_msg.statuscode=VEN_S_SUCCESS;
2868 venc_handle->async_message_process(venc_handle,&venc_msg);
2869 return 0;
2870 }
2871
venc_set_message_thread_id(pthread_t tid)2872 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2873 {
2874 async_thread_created = true;
2875 m_tid=tid;
2876 return 0;
2877 }
2878
venc_set_vqzip_defaults()2879 bool venc_dev::venc_set_vqzip_defaults()
2880 {
2881 struct v4l2_control control;
2882 int rc = 0, num_mbs_per_frame;
2883
2884 num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
2885
2886 switch (num_mbs_per_frame) {
2887 case OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT:
2888 case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
2889 case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
2890 case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
2891 break;
2892 default:
2893 DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
2894 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
2895 return false;
2896 }
2897
2898 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
2899 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
2900 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2901 if (rc)
2902 DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
2903 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
2904 control.value = INT_MAX;
2905
2906 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2907 if (rc)
2908 DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
2909
2910 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
2911 control.value = 0;
2912
2913 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2914 if (rc)
2915 DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
2916
2917 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
2918 control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
2919
2920 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2921 if (rc)
2922 DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
2923
2924 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2925 control.value = 1;
2926
2927 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2928 if (rc)
2929 DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP");
2930
2931 return true;
2932 }
2933
2934
venc_start(void)2935 unsigned venc_dev::venc_start(void)
2936 {
2937 enum v4l2_buf_type buf_type;
2938 int ret, r;
2939 struct v4l2_control control;
2940
2941 memset(&control, 0, sizeof(control));
2942
2943 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2944 __func__);
2945 m_level_set = false;
2946
2947 if (!venc_set_profile_level(0, 0)) {
2948 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2949 __func__);
2950 } else {
2951 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2952 __func__, codec_profile.profile, profile_level.level);
2953 }
2954
2955 if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
2956 return 1;
2957
2958 // disable B-frames for realtime high-resolution/fps usecases for power considerations
2959 if (intra_period.num_bframes &&
2960 sess_priority.priority == 0 /*realtime*/ &&
2961 (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) ||
2962 (operating_rate >= 60 << 16))) {
2963 intra_period.num_pframes += (intra_period.num_bframes + 1);
2964 intra_period.num_bframes = 0;
2965 if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
2966 DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec",
2967 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16);
2968 } else {
2969 DEBUG_PRINT_ERROR("Failed to disable B frames!");
2970 }
2971 }
2972
2973 // re-configure the temporal layers as RC-mode and key-frame interval
2974 // might have changed since the client last configured the layers.
2975 if (temporal_layers_config.nPLayers) {
2976 if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2977 DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2978 } else {
2979 // request buffers on capture port again since internal (scratch)-
2980 // buffer requirements may change (i.e if we switch from non-hybrid
2981 // to hybrid mode and vice-versa)
2982 struct v4l2_requestbuffers bufreq;
2983
2984 bufreq.memory = V4L2_MEMORY_USERPTR;
2985 bufreq.count = m_sOutput_buff_property.actualcount;
2986 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2987 if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2988 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2989 }
2990 }
2991 }
2992
2993 venc_config_print();
2994
2995 if(resume_in_stopped){
2996 /*set buffercount when restarted*/
2997 venc_reconfig_reqbufs();
2998 resume_in_stopped = 0;
2999 }
3000
3001 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
3002 if (slice_mode.enable && multislice.mslice_size &&
3003 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
3004 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
3005 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
3006 MAX_SUPPORTED_SLICES_PER_FRAME);
3007 return 1;
3008 }
3009
3010 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3011 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
3012 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
3013
3014 if (ret)
3015 return 1;
3016
3017 streaming[CAPTURE_PORT] = true;
3018
3019 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
3020 control.value = 1;
3021 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3022 if (ret) {
3023 DEBUG_PRINT_ERROR("failed to request seq header");
3024 return 1;
3025 }
3026
3027
3028 stopped = 0;
3029 return 0;
3030 }
3031
hiermode_string(int val)3032 inline const char* hiermode_string(int val)
3033 {
3034 switch(val)
3035 {
3036 case HIER_NONE:
3037 return "No Hier";
3038 case HIER_P:
3039 return "Hier-P";
3040 case HIER_B:
3041 return "Hier-B";
3042 case HIER_P_HYBRID:
3043 return "Hybrid Hier-P";
3044 default:
3045 return "No hier";
3046 }
3047 }
3048
bitrate_type_string(int val)3049 inline const char* bitrate_type_string(int val)
3050 {
3051 switch(val)
3052 {
3053 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
3054 return "CUMULATIVE";
3055 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
3056 return "LAYER WISE";
3057 default:
3058 return "Unknown Bitrate Type";
3059 }
3060 }
3061
codec_as_string(unsigned long codec)3062 static const char *codec_as_string(unsigned long codec) {
3063 switch (codec) {
3064 case V4L2_PIX_FMT_H264:
3065 return "H264";
3066 case V4L2_PIX_FMT_MPEG4:
3067 return "MPEG4";
3068 case V4L2_PIX_FMT_H263:
3069 return "H263";
3070 case V4L2_PIX_FMT_HEVC:
3071 return "HEVC";
3072 case V4L2_PIX_FMT_VP8:
3073 return "VP8";
3074 default:
3075 return "UNKOWN";
3076 }
3077 }
3078
venc_config_print()3079 void venc_dev::venc_config_print()
3080 {
3081
3082 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
3083 codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
3084
3085 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
3086 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
3087 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3088
3089 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
3090 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
3091 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3092
3093 DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
3094 color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
3095
3096 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
3097 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
3098
3099 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
3100 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
3101
3102 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
3103 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
3104
3105 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
3106 session_qp_values.minqp, session_qp_values.maxqp);
3107
3108 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
3109 voptimecfg.voptime_resolution, multislice.mslice_mode,
3110 multislice.mslice_size);
3111
3112 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
3113 entropy.longentropysel, entropy.cabacmodel);
3114
3115 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
3116 dbkfilter.db_mode, dbkfilter.slicealpha_offset,
3117 dbkfilter.slicebeta_offset);
3118
3119 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
3120 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
3121
3122 DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
3123 ltrinfo.enabled, ltrinfo.count);
3124
3125 if (temporal_layers_config.nPLayers) {
3126 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
3127 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
3128 intra_period.num_pframes + intra_period.num_bframes + 1);
3129
3130 for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
3131 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
3132 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
3133 l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
3134 }
3135 } else {
3136
3137 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
3138 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
3139
3140 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
3141 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
3142
3143 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
3144 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
3145 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
3146 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
3147 }
3148
3149 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
3150
3151 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
3152
3153 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
3154
3155 DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
3156
3157 DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
3158 }
3159
venc_reconfig_reqbufs()3160 bool venc_dev::venc_reconfig_reqbufs()
3161 {
3162 struct v4l2_requestbuffers bufreq;
3163
3164 bufreq.memory = V4L2_MEMORY_USERPTR;
3165 bufreq.count = m_sInput_buff_property.actualcount;
3166 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3167 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3168 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
3169 return false;
3170 }
3171
3172 bufreq.memory = V4L2_MEMORY_USERPTR;
3173 bufreq.count = m_sOutput_buff_property.actualcount;
3174 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3175 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
3176 {
3177 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
3178 return false;
3179 }
3180 return true;
3181 }
3182
venc_flush(unsigned port)3183 unsigned venc_dev::venc_flush( unsigned port)
3184 {
3185 struct v4l2_encoder_cmd enc;
3186 DEBUG_PRINT_LOW("in %s", __func__);
3187
3188 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
3189 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3190
3191 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
3192 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
3193 return -1;
3194 }
3195
3196 return 0;
3197
3198 }
3199
3200 //allocating I/P memory from pmem and register with the device
3201
3202
venc_use_buf(void * buf_addr,unsigned port,unsigned index)3203 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
3204 {
3205
3206 struct pmem *pmem_tmp;
3207 struct v4l2_buffer buf;
3208 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3209 int rc = 0;
3210 unsigned int extra_idx;
3211
3212 pmem_tmp = (struct pmem *)buf_addr;
3213 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
3214
3215 if (port == PORT_INDEX_OUT) {
3216 extra_idx = EXTRADATA_IDX(num_output_planes);
3217 buf.index = index;
3218 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3219 buf.memory = V4L2_MEMORY_USERPTR;
3220 plane[0].length = pmem_tmp->size;
3221 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
3222 plane[0].reserved[0] = pmem_tmp->fd;
3223 plane[0].reserved[1] = 0;
3224 plane[0].data_offset = pmem_tmp->offset;
3225 buf.m.planes = plane;
3226 buf.length = num_output_planes;
3227
3228 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3229 char *userptr;
3230 int fd;
3231 unsigned offset;
3232 ssize_t size;
3233 int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size);
3234 if (rc != OMX_ErrorNone) {
3235 DEBUG_PRINT_ERROR("Unable to get extradata memory 2");
3236 return rc;
3237 }
3238 plane[extra_idx].length = size;
3239 plane[extra_idx].m.userptr = (unsigned long)userptr;
3240 #ifdef USE_ION
3241 plane[extra_idx].reserved[0] = fd;
3242 #endif
3243 plane[extra_idx].reserved[1] = offset;
3244 plane[extra_idx].data_offset = 0;
3245 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3246 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
3247 return OMX_ErrorBadParameter;
3248 }
3249
3250 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
3251
3252 if (rc)
3253 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
3254 } else if (port == PORT_INDEX_IN) {
3255 DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port");
3256 } else {
3257 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
3258 return false;
3259 }
3260
3261 return true;
3262 }
3263
venc_free_buf(void * buf_addr,unsigned port)3264 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
3265 {
3266 struct pmem *pmem_tmp;
3267 struct venc_bufferpayload dev_buffer;
3268
3269 memset(&dev_buffer, 0, sizeof(dev_buffer));
3270 pmem_tmp = (struct pmem *)buf_addr;
3271
3272 if (port == PORT_INDEX_IN) {
3273 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3274 dev_buffer.fd = pmem_tmp->fd;
3275 dev_buffer.maped_size = pmem_tmp->size;
3276 dev_buffer.sz = pmem_tmp->size;
3277 dev_buffer.offset = pmem_tmp->offset;
3278 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3279 dev_buffer.pbuffer, \
3280 dev_buffer.fd, \
3281 dev_buffer.offset, \
3282 dev_buffer.maped_size);
3283
3284 } else if (port == PORT_INDEX_OUT) {
3285 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3286 dev_buffer.fd = pmem_tmp->fd;
3287 dev_buffer.sz = pmem_tmp->size;
3288 dev_buffer.maped_size = pmem_tmp->size;
3289 dev_buffer.offset = pmem_tmp->offset;
3290
3291 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3292 dev_buffer.pbuffer, \
3293 dev_buffer.fd, \
3294 dev_buffer.offset, \
3295 dev_buffer.maped_size);
3296 } else {
3297 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
3298 return false;
3299 }
3300
3301 return true;
3302 }
3303
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3304 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
3305 OMX_U32 width, OMX_U32 height)
3306 {
3307 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
3308 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
3309 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
3310 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
3311 src_chroma_offset = width * height;
3312
3313 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
3314 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3315 //Do chroma first, so that we can convert it in-place
3316 src_buf += width * height;
3317 dst_buf += y_stride * y_scanlines;
3318 for (int line = height / 2 - 1; line >= 0; --line) {
3319 memmove(dst_buf + line * uv_stride,
3320 src_buf + line * width,
3321 width);
3322 }
3323
3324 dst_buf = src_buf = buffer->pBuffer;
3325 //Copy the Y next
3326 for (int line = height - 1; line > 0; --line) {
3327 memmove(dst_buf + line * y_stride,
3328 src_buf + line * width,
3329 width);
3330 }
3331 } else {
3332 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3333 Insufficient bufferLen=%u v/s Required=%u",
3334 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3335 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3336 return false;
3337 }
3338
3339 return true;
3340 }
3341
venc_get_performance_level(OMX_U32 * perflevel)3342 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
3343 {
3344 if (!perflevel) {
3345 DEBUG_PRINT_ERROR("Null pointer error");
3346 return false;
3347 } else {
3348 *perflevel = performance_level.perflevel;
3349 return true;
3350 }
3351 }
3352
venc_get_vui_timing_info(OMX_U32 * enabled)3353 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
3354 {
3355 if (!enabled) {
3356 DEBUG_PRINT_ERROR("Null pointer error");
3357 return false;
3358 } else {
3359 *enabled = vui_timing_info.enabled;
3360 return true;
3361 }
3362 }
3363
venc_get_vqzip_sei_info(OMX_U32 * enabled)3364 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
3365 {
3366 if (!enabled) {
3367 DEBUG_PRINT_ERROR("Null pointer error");
3368 return false;
3369 } else {
3370 *enabled = vqzip_sei_info.enabled;
3371 return true;
3372 }
3373 }
3374
venc_get_peak_bitrate(OMX_U32 * peakbitrate)3375 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
3376 {
3377 if (!peakbitrate) {
3378 DEBUG_PRINT_ERROR("Null pointer error");
3379 return false;
3380 } else {
3381 *peakbitrate = peak_bitrate.peakbitrate;
3382 return true;
3383 }
3384 }
3385
venc_get_batch_size(OMX_U32 * size)3386 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
3387 {
3388 if (!size) {
3389 DEBUG_PRINT_ERROR("Null pointer error");
3390 return false;
3391 } else {
3392 *size = mBatchSize;
3393 return true;
3394 }
3395 }
3396
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3397 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
3398 {
3399 struct pmem *temp_buffer;
3400 struct v4l2_buffer buf;
3401 struct v4l2_requestbuffers bufreq;
3402 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3403 int rc = 0, extra_idx;
3404 struct OMX_BUFFERHEADERTYPE *bufhdr;
3405 encoder_media_buffer_type * meta_buf = NULL;
3406 temp_buffer = (struct pmem *)buffer;
3407
3408 memset (&buf, 0, sizeof(buf));
3409 memset (&plane, 0, sizeof(plane));
3410
3411 if (buffer == NULL) {
3412 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
3413 return false;
3414 }
3415
3416 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3417 bufreq.memory = V4L2_MEMORY_USERPTR;
3418 bufreq.count = m_sInput_buff_property.actualcount;
3419 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3420
3421 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
3422
3423 if (pmem_data_buf) {
3424 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
3425 plane[0].m.userptr = (unsigned long)pmem_data_buf;
3426 plane[0].data_offset = bufhdr->nOffset;
3427 plane[0].length = bufhdr->nAllocLen;
3428 plane[0].bytesused = bufhdr->nFilledLen;
3429 } else {
3430 // --------------------------------------------------------------------------------------
3431 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info]
3432 // ---------------------------------------------------------------------------------------
3433 // Camera-2 1 CameraSource 0 meta-handle
3434 // Camera-3 1 GrallocSource 0 gralloc-private-handle
3435 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted)
3436 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr
3437 // ---------------------------------------------------------------------------------------
3438 if (metadatamode) {
3439 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3440 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3441
3442 if (!meta_buf) {
3443 //empty EOS buffer
3444 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
3445 plane[0].data_offset = bufhdr->nOffset;
3446 plane[0].length = bufhdr->nAllocLen;
3447 plane[0].bytesused = bufhdr->nFilledLen;
3448 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
3449 } else {
3450 return false;
3451 }
3452 } else if (!color_format) {
3453 int usage = 0;
3454
3455 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3456 native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
3457 if (!hnd) {
3458 DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
3459 return false;
3460 }
3461
3462 if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
3463 usage = hnd->data[3];
3464 } else if (mBatchSize) {
3465 usage = BatchInfo::getColorFormatAt(hnd, 0);
3466 }
3467 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
3468 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3469 }
3470
3471 if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
3472 m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
3473 struct v4l2_format fmt;
3474
3475 memset(&fmt, 0, sizeof(fmt));
3476 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
3477 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
3478 DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
3479 DEBUG_PRINT_ERROR(" This leads to unknown color space");
3480 }
3481 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
3482 if (is_csc_enabled) {
3483 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3484 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3485 venc_set_colorspace(MSM_VIDC_BT709_5, 1,
3486 MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
3487 } else {
3488 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
3489 MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3490 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3491 }
3492 }
3493 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3494 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3495 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3496 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3497 if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
3498 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
3499 }
3500 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3501 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3502 DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
3503 return false;
3504 }
3505 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3506 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3507 return false;
3508 }
3509 }
3510
3511 // Setting batch mode is sticky. We do not expect camera to change
3512 // between batch and normal modes at runtime.
3513 if (mBatchSize) {
3514 if ((unsigned)hnd->numFds != mBatchSize) {
3515 DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
3516 mBatchSize, hnd->numFds);
3517 return false;
3518 }
3519
3520 return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
3521 }
3522
3523 if (hnd->numFds + hnd->numInts > 2) {
3524 plane[0].data_offset = hnd->data[1];
3525 plane[0].length = hnd->data[2];
3526 plane[0].bytesused = hnd->data[2];
3527 }
3528 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
3529 fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
3530 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
3531 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
3532
3533 if (!handle) {
3534 DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
3535 return false;
3536 }
3537
3538 if (mUseAVTimerTimestamps) {
3539 uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
3540 if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
3541 && avTimerTimestampNs > 0) {
3542 bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
3543 DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
3544 }
3545 }
3546
3547 if (!streaming[OUTPUT_PORT]) {
3548 // Moment of truth... actual colorspace is known here..
3549 ColorSpace_t colorSpace = ITU_R_601;
3550 if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
3551 DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3552 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3553 }
3554
3555 struct v4l2_format fmt;
3556 memset(&fmt, 0, sizeof(fmt));
3557 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3558
3559 bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
3560 if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3561 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
3562 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
3563 } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
3564 // In case of RGB, conversion to YUV is handled within encoder.
3565 // Disregard the Colorspace in gralloc-handle in case of RGB and use
3566 // [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
3567 // [b] 601 for UBWC case : Venus can convert to 601-LR or FR. use LR for now.
3568 colorSpace = ITU_R_601;
3569 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
3570 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
3571 } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3572 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3573 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
3574 }
3575
3576 // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
3577 if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
3578 struct v4l2_control control;
3579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
3580 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
3581 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3582 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
3583 } else {
3584 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
3585 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3586 colorSpace = ITU_R_709;
3587 }
3588 }
3589
3590 msm_vidc_h264_color_primaries_values primary;
3591 msm_vidc_h264_transfer_chars_values transfer;
3592 msm_vidc_h264_matrix_coeff_values matrix;
3593 OMX_U32 range;
3594
3595 switch (colorSpace) {
3596 case ITU_R_601_FR:
3597 {
3598 primary = MSM_VIDC_BT601_6_525;
3599 range = 1; // full
3600 transfer = MSM_VIDC_TRANSFER_601_6_525;
3601 matrix = MSM_VIDC_MATRIX_601_6_525;
3602
3603 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3604 break;
3605 }
3606 case ITU_R_709:
3607 {
3608 primary = MSM_VIDC_BT709_5;
3609 range = 0; // limited
3610 transfer = MSM_VIDC_TRANSFER_BT709_5;
3611 matrix = MSM_VIDC_MATRIX_BT_709_5;
3612
3613 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3614 break;
3615 }
3616 default:
3617 {
3618 // 601 or something else ? assume 601
3619 primary = MSM_VIDC_BT601_6_625;
3620 range = 0; //limited
3621 transfer = MSM_VIDC_TRANSFER_601_6_625;
3622 matrix = MSM_VIDC_MATRIX_601_6_625;
3623
3624 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3625 break;
3626 }
3627 }
3628 DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3629 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3630 venc_set_colorspace(primary, range, transfer, matrix);
3631
3632 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3633 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3634 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3635 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3636 DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
3637 return false;
3638 }
3639 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3640 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3641 return false;
3642 }
3643 }
3644
3645 fd = handle->fd;
3646 plane[0].data_offset = 0;
3647 plane[0].length = handle->size;
3648 plane[0].bytesused = handle->size;
3649 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
3650 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
3651 }
3652 } else {
3653 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3654 plane[0].data_offset = bufhdr->nOffset;
3655 plane[0].length = bufhdr->nAllocLen;
3656 plane[0].bytesused = bufhdr->nFilledLen;
3657 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
3658 fd, plane[0].bytesused, plane[0].length);
3659 }
3660 } else {
3661 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3662 plane[0].data_offset = bufhdr->nOffset;
3663 plane[0].length = bufhdr->nAllocLen;
3664 plane[0].bytesused = bufhdr->nFilledLen;
3665 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
3666 fd, plane[0].bytesused, plane[0].length);
3667 }
3668 }
3669
3670 extra_idx = EXTRADATA_IDX(num_input_planes);
3671
3672 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3673 char *userptr;
3674 int fd;
3675 unsigned offset;
3676 ssize_t size;
3677 int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
3678 if (rc != OMX_ErrorNone) {
3679 DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
3680 return rc;
3681 }
3682 plane[extra_idx].bytesused = 0;
3683 plane[extra_idx].length = size;
3684 plane[extra_idx].m.userptr = (unsigned long) userptr;
3685 #ifdef USE_ION
3686 plane[extra_idx].reserved[0] = fd;
3687 #endif
3688 plane[extra_idx].reserved[1] = offset;
3689 plane[extra_idx].data_offset = 0;
3690 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3691 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3692 return false;
3693 }
3694
3695 buf.index = index;
3696 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3697 buf.memory = V4L2_MEMORY_USERPTR;
3698 plane[0].reserved[0] = fd;
3699 plane[0].reserved[1] = 0;
3700 buf.m.planes = plane;
3701 buf.length = num_input_planes;
3702
3703 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3704 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3705
3706 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3707 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3708 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3709
3710 if (rc) {
3711 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3712 return false;
3713 }
3714
3715 etb++;
3716
3717 if (!streaming[OUTPUT_PORT]) {
3718 enum v4l2_buf_type buf_type;
3719 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3720 int ret;
3721 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3722
3723 if (ret) {
3724 DEBUG_PRINT_ERROR("Failed to call streamon");
3725 if (errno == EBUSY) {
3726 hw_overload = true;
3727 }
3728 return false;
3729 } else {
3730 streaming[OUTPUT_PORT] = true;
3731 }
3732 }
3733 if (m_debug.in_buffer_log) {
3734 venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
3735 }
3736
3737 return true;
3738 }
3739
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3740 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3741 {
3742 struct v4l2_buffer buf;
3743 struct v4l2_plane plane;
3744 int rc = 0;
3745 struct v4l2_control control;
3746 encoder_media_buffer_type * meta_buf = NULL;
3747 native_handle_t *hnd = NULL;
3748
3749 if (bufhdr == NULL) {
3750 DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3751 return false;
3752 }
3753
3754 bool status = true;
3755 if (metadatamode) {
3756 plane.m.userptr = (unsigned long)bufhdr->pBuffer;
3757 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3758
3759 if (!color_format) {
3760 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3761 hnd = (native_handle_t*)meta_buf->meta_handle;
3762 if (!hnd) {
3763 DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3764 return false;
3765 } else if (hnd->numFds > kMaxBuffersInBatch) {
3766 DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3767 "Max = %d", hnd->numFds, kMaxBuffersInBatch);
3768 status = false;
3769 }
3770 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
3771 } else {
3772 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3773 status = false;
3774 }
3775 } else {
3776 DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3777 status = false;
3778 }
3779 } else {
3780 DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3781 status = false;
3782 }
3783
3784 if (status) {
3785 OMX_TICKS bufTimeStamp = 0ll;
3786 int numBufs = hnd->numFds;
3787 int v4l2Ids[kMaxBuffersInBatch] = {-1};
3788 for (int i = 0; i < numBufs; ++i) {
3789 v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3790 if (v4l2Ids[i] < 0) {
3791 DEBUG_PRINT_ERROR("Failed to register buffer");
3792 // TODO: cleanup the map and purge all slots of current index
3793 status = false;
3794 break;
3795 }
3796 }
3797 for (int i = 0; i < numBufs; ++i) {
3798 int v4l2Id = v4l2Ids[i];
3799
3800 memset(&buf, 0, sizeof(buf));
3801 memset(&plane, 0, sizeof(plane));
3802
3803 DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3804 buf.index = (unsigned)v4l2Id;
3805 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3806 buf.memory = V4L2_MEMORY_USERPTR;
3807 plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
3808 plane.reserved[1] = 0;
3809 plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
3810 plane.m.userptr = (unsigned long)meta_buf;
3811 plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
3812 buf.m.planes = &plane;
3813 buf.length = 1;
3814
3815 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3816 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3817 if (i != numBufs - 1) {
3818 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3819 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
3820 i, etb + 1, numBufs);
3821 }
3822
3823
3824 // timestamp differences from camera are in nano-seconds
3825 bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
3826
3827 DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3828 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
3829 buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3830 buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3831
3832 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3833 if (rc) {
3834 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3835 return false;
3836 }
3837
3838 etb++;
3839 }
3840 }
3841
3842 if (status && !streaming[OUTPUT_PORT]) {
3843 enum v4l2_buf_type buf_type;
3844 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3845 int ret;
3846 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3847 if (ret) {
3848 DEBUG_PRINT_ERROR("Failed to call streamon");
3849 if (errno == EBUSY) {
3850 hw_overload = true;
3851 }
3852 status = false;
3853 } else {
3854 streaming[OUTPUT_PORT] = true;
3855 }
3856 }
3857
3858 return status;
3859 }
3860
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3861 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3862 {
3863 struct pmem *temp_buffer = NULL;
3864 struct venc_buffer frameinfo;
3865 struct v4l2_buffer buf;
3866 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3867 int rc = 0;
3868 unsigned int extra_idx;
3869 struct OMX_BUFFERHEADERTYPE *bufhdr;
3870
3871 if (buffer == NULL)
3872 return false;
3873
3874 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3875
3876 if (pmem_data_buf) {
3877 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3878 plane[0].m.userptr = (unsigned long)pmem_data_buf;
3879 } else {
3880 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3881 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3882 }
3883
3884 memset(&buf, 0, sizeof(buf));
3885 memset(&plane, 0, sizeof(plane));
3886
3887 buf.index = index;
3888 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3889 buf.memory = V4L2_MEMORY_USERPTR;
3890 plane[0].length = bufhdr->nAllocLen;
3891 plane[0].bytesused = bufhdr->nFilledLen;
3892 plane[0].reserved[0] = fd;
3893 plane[0].reserved[1] = 0;
3894 plane[0].data_offset = bufhdr->nOffset;
3895 buf.m.planes = plane;
3896 buf.length = num_output_planes;
3897 buf.flags = 0;
3898
3899 if (mBatchSize) {
3900 // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
3901 // This results in the first batch being of size mBatchSize + 1, but thats good because
3902 // we need an extra FTB for the codec specific data.
3903
3904 if (!ftb || ftb % mBatchSize) {
3905 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3906 DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
3907 }
3908 }
3909
3910 extra_idx = EXTRADATA_IDX(num_output_planes);
3911
3912 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3913 char *userptr;
3914 int fd;
3915 unsigned offset;
3916 ssize_t size;
3917 int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
3918 if (rc != OMX_ErrorNone) {
3919 DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
3920 return false;
3921 }
3922 plane[extra_idx].bytesused = 0;
3923 plane[extra_idx].length = size;
3924 plane[extra_idx].m.userptr = (unsigned long)userptr;
3925 #ifdef USE_ION
3926 plane[extra_idx].reserved[0] = fd;
3927 #endif
3928 plane[extra_idx].reserved[1] = offset;
3929 plane[extra_idx].data_offset = 0;
3930 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3931 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3932 return false;
3933 }
3934
3935 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3936
3937 if (rc) {
3938 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3939 return false;
3940 }
3941
3942 ftb++;
3943 return true;
3944 }
3945
venc_set_inband_video_header(OMX_BOOL enable)3946 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
3947 {
3948 struct v4l2_control control;
3949
3950 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
3951 if(enable) {
3952 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
3953 } else {
3954 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
3955 }
3956
3957 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
3958 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3959 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
3960 return false;
3961 }
3962 return true;
3963 }
3964
venc_set_au_delimiter(OMX_BOOL enable)3965 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
3966 {
3967 struct v4l2_control control;
3968
3969 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
3970 if(enable) {
3971 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
3972 } else {
3973 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
3974 }
3975
3976 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
3977 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3978 DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
3979 return false;
3980 }
3981 return true;
3982 }
3983
venc_set_mbi_statistics_mode(OMX_U32 mode)3984 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
3985 {
3986 struct v4l2_control control;
3987
3988 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
3989 control.value = mode;
3990
3991 DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
3992 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3993 DEBUG_PRINT_ERROR("Setting MBI mode failed");
3994 return false;
3995 }
3996 return true;
3997 }
3998
venc_set_vqzip_sei_type(OMX_BOOL enable)3999 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
4000 {
4001 struct v4l2_control sei_control, yuvstats_control;
4002
4003 DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
4004 sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
4005 yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4006
4007 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
4008 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
4009 }
4010
4011 if(enable) {
4012 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
4013 yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4014 } else {
4015 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
4016 yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4017 }
4018
4019 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
4020 DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
4021 }
4022
4023 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
4024 DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
4025 }
4026 #ifdef _VQZIP_
4027 vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
4028 vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
4029 vqzip.init();
4030 vqzip_sei_info.enabled = true;
4031 #endif
4032
4033 return true;
4034 }
4035
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)4036 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
4037 {
4038 // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
4039 if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
4040 return false;
4041
4042 // Check for bframes with Hier-P-Hybrid
4043 if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
4044 return false;
4045
4046 // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
4047 if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
4048 hier_layers.hier_mode == HIER_B || ltrinfo.count))
4049 return false;
4050
4051 // Check for LTR with Hier-P-Hybrid
4052 if (count && hier_layers.hier_mode == HIER_P_HYBRID)
4053 return false;
4054
4055 return true;
4056 }
4057
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)4058 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
4059 OMX_U32 num_layers)
4060 {
4061 struct v4l2_control control;
4062
4063 if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
4064 DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
4065 return false;
4066 }
4067
4068 if (type == QOMX_HIERARCHICALCODING_P) {
4069 // Reduce layer count by 1 before sending to driver. This avoids
4070 // driver doing the same in multiple places.
4071 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
4072 control.value = num_layers - 1;
4073 DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
4074 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4075 DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
4076 return false;
4077 }
4078 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
4079 control.value = num_layers - 1;
4080 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
4081 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4082 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4083 return false;
4084 }
4085 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4086 DEBUG_PRINT_LOW("Set H264_SVC_NAL");
4087 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4088 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4089 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4090 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4091 return false;
4092 }
4093 }
4094 hier_layers.hier_mode = HIER_P;
4095 } else if (type == QOMX_HIERARCHICALCODING_B) {
4096 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4097 DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
4098 return false;
4099 }
4100 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
4101 control.value = num_layers - 1;
4102 DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
4103 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4104 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4105 return false;
4106 }
4107 hier_layers.hier_mode = HIER_B;
4108 } else {
4109 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
4110 return false;
4111 }
4112 hier_layers.numlayers = num_layers;
4113 return true;
4114 }
4115
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)4116 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
4117 {
4118 struct v4l2_control control;
4119
4120 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
4121
4122 if (enable == OMX_FALSE) {
4123 /* No easy way to turn off extradata to the driver
4124 * at the moment */
4125 return false;
4126 }
4127
4128 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4129 switch (extra_data) {
4130 case OMX_ExtraDataVideoEncoderSliceInfo:
4131 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
4132 break;
4133 case OMX_ExtraDataVideoEncoderMBInfo:
4134 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
4135 break;
4136 case OMX_ExtraDataFrameDimension:
4137 control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
4138 break;
4139 default:
4140 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
4141 return false;
4142 }
4143
4144 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4145 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
4146 (unsigned int)extra_data, errno);
4147 return false;
4148 }
4149
4150 return true;
4151 }
4152
venc_set_slice_delivery_mode(OMX_U32 enable)4153 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
4154 {
4155 struct v4l2_control control;
4156
4157 if (enable) {
4158 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
4159 control.value = 1;
4160 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
4161
4162 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4163 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4164 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
4165 return false;
4166 } else {
4167 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
4168 slice_mode.enable = 1;
4169 }
4170 } else {
4171 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
4172 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
4173 m_sVenc_cfg.codectype);
4174 }
4175 } else {
4176 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
4177 }
4178
4179 return true;
4180 }
4181
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)4182 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
4183 {
4184 int rc;
4185 struct v4l2_control control;
4186 struct v4l2_ext_control ctrl[4];
4187 struct v4l2_ext_controls controls;
4188
4189 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
4190 ctrl[0].value = initqp->nQpI;
4191 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
4192 ctrl[1].value = initqp->nQpP;
4193 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
4194 ctrl[2].value = initqp->nQpB;
4195 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
4196 ctrl[3].value = initqp->bEnableInitQp;
4197
4198 controls.count = 4;
4199 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4200 controls.controls = ctrl;
4201
4202 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4203 controls.controls[0].id, controls.controls[0].value,
4204 controls.controls[1].id, controls.controls[1].value,
4205 controls.controls[2].id, controls.controls[2].value,
4206 controls.controls[3].id, controls.controls[3].value);
4207
4208 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4209 if (rc) {
4210 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
4211 return false;
4212 }
4213
4214 init_qp.iframeqp = initqp->nQpI;
4215 init_qp.pframeqp = initqp->nQpP;
4216 init_qp.bframeqp = initqp->nQpB;
4217 init_qp.enableinitqp = initqp->bEnableInitQp;
4218
4219 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4220 controls.controls[0].id, controls.controls[0].value,
4221 controls.controls[1].id, controls.controls[1].value,
4222 controls.controls[2].id, controls.controls[2].value,
4223 controls.controls[3].id, controls.controls[3].value);
4224 return true;
4225 }
4226
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)4227 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
4228 OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
4229 {
4230 int rc;
4231 struct v4l2_control control;
4232
4233 DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
4234 primaries, range, transfer_chars, matrix_coeffs);
4235
4236 control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
4237 control.value = primaries;
4238
4239 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4240 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4241
4242 if (rc) {
4243 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
4244 return false;
4245 }
4246
4247 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4248
4249 color_space.primaries = control.value;
4250
4251 control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
4252 control.value = range;
4253
4254 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4255 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4256
4257 if (rc) {
4258 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
4259 return false;
4260 }
4261
4262 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4263
4264 color_space.range = control.value;
4265
4266 control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
4267 control.value = transfer_chars;
4268
4269 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4270 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4271
4272 if (rc) {
4273 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
4274 return false;
4275 }
4276
4277 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4278
4279 color_space.transfer_chars = control.value;
4280
4281 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
4282 control.value = matrix_coeffs;
4283
4284 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4285 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4286
4287 if (rc) {
4288 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
4289 return false;
4290 }
4291
4292 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4293
4294 color_space.matrix_coeffs = control.value;
4295
4296 return true;
4297 }
4298
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)4299 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
4300 {
4301 int rc;
4302 struct v4l2_control control;
4303
4304 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
4305 control.value = i_frame_qp;
4306
4307 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4308 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4309
4310 if (rc) {
4311 DEBUG_PRINT_ERROR("Failed to set control");
4312 return false;
4313 }
4314
4315 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4316 session_qp.iframeqp = control.value;
4317
4318 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
4319 control.value = p_frame_qp;
4320
4321 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4322 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4323
4324 if (rc) {
4325 DEBUG_PRINT_ERROR("Failed to set control");
4326 return false;
4327 }
4328
4329 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4330
4331 session_qp.pframeqp = control.value;
4332
4333 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
4334 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4335
4336 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
4337 control.value = b_frame_qp;
4338
4339 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4340 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4341
4342 if (rc) {
4343 DEBUG_PRINT_ERROR("Failed to set control");
4344 return false;
4345 }
4346
4347 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4348
4349 session_qp.bframeqp = control.value;
4350 }
4351
4352 return true;
4353 }
4354
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)4355 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
4356 {
4357 int rc;
4358 struct v4l2_control control;
4359
4360 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
4361
4362 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4363 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
4364 else
4365 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
4366 control.value = min_qp;
4367
4368 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
4369 control.id, control.value);
4370 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4371 if (rc) {
4372 DEBUG_PRINT_ERROR("Failed to set control");
4373 return false;
4374 }
4375
4376 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4377 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
4378 else
4379 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
4380 control.value = max_qp;
4381
4382 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
4383 control.id, control.value);
4384 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4385 if (rc) {
4386 DEBUG_PRINT_ERROR("Failed to set control");
4387 return false;
4388 }
4389 } else {
4390 DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
4391 (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
4392 }
4393
4394 return true;
4395 }
4396
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)4397 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
4398 {
4399 struct venc_profile requested_profile = {0};
4400 struct ven_profilelevel requested_level = {0};
4401 unsigned long mb_per_frame = 0;
4402 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
4403 (unsigned int)eProfile, (unsigned int)eLevel);
4404 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4405 ((m_sVenc_cfg.dvs_width + 15) >> 4);
4406
4407 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
4408 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
4409 return true;
4410 }
4411
4412 if (vqzip_sei_info.enabled) {
4413 DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
4414 return true;
4415 }
4416
4417 DEBUG_PRINT_LOW("Validating Profile/Level from table");
4418
4419 if (!venc_validate_profile_level(&eProfile, &eLevel)) {
4420 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
4421 return false;
4422 }
4423
4424 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4425 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
4426 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
4427 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
4428
4429 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4430 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
4431 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4432 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
4433 } else {
4434 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
4435 (unsigned int)eProfile);
4436 return false;
4437 }
4438
4439 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
4440 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
4441 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
4442 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
4443
4444 if (mb_per_frame >= 3600) {
4445 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4446 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4447
4448 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4449 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4450 } else {
4451 switch (eLevel) {
4452 case OMX_VIDEO_MPEG4Level0:
4453 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
4454 break;
4455 case OMX_VIDEO_MPEG4Level0b:
4456 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
4457 break;
4458 case OMX_VIDEO_MPEG4Level1:
4459 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
4460 break;
4461 case OMX_VIDEO_MPEG4Level2:
4462 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
4463 break;
4464 case OMX_VIDEO_MPEG4Level3:
4465 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
4466 break;
4467 case OMX_VIDEO_MPEG4Level4a:
4468 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
4469 break;
4470 case OMX_VIDEO_MPEG4Level5:
4471 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4472 break;
4473 default:
4474 return false;
4475 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
4476 break;
4477 }
4478 }
4479 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4480
4481 switch (eProfile) {
4482 case OMX_VIDEO_H263ProfileBaseline:
4483 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
4484 break;
4485 case OMX_VIDEO_H263ProfileH320Coding:
4486 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
4487 break;
4488 case OMX_VIDEO_H263ProfileBackwardCompatible:
4489 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
4490 break;
4491 case OMX_VIDEO_H263ProfileISWV2:
4492 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
4493 break;
4494 case OMX_VIDEO_H263ProfileISWV3:
4495 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
4496 break;
4497 case OMX_VIDEO_H263ProfileHighCompression:
4498 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
4499 break;
4500 case OMX_VIDEO_H263ProfileInternet:
4501 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
4502 break;
4503 case OMX_VIDEO_H263ProfileInterlace:
4504 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
4505 break;
4506 case OMX_VIDEO_H263ProfileHighLatency:
4507 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
4508 break;
4509 default:
4510 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
4511 requested_profile.profile);
4512 return false;
4513 }
4514
4515 //profile level
4516 switch (eLevel) {
4517 case OMX_VIDEO_H263Level10:
4518 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
4519 break;
4520 case OMX_VIDEO_H263Level20:
4521 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
4522 break;
4523 case OMX_VIDEO_H263Level30:
4524 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
4525 break;
4526 case OMX_VIDEO_H263Level40:
4527 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
4528 break;
4529 case OMX_VIDEO_H263Level45:
4530 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
4531 break;
4532 case OMX_VIDEO_H263Level50:
4533 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
4534 break;
4535 case OMX_VIDEO_H263Level60:
4536 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
4537 break;
4538 case OMX_VIDEO_H263Level70:
4539 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
4540 break;
4541 default:
4542 return false;
4543 break;
4544 }
4545 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4546 if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
4547 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
4548 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
4549 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
4550 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh) {
4551 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
4552 } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
4553 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
4554 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
4555 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
4556 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
4557 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
4558 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
4559 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
4560 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
4561 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
4562 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
4563 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
4564 } else {
4565 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
4566 requested_profile.profile);
4567 return false;
4568 }
4569
4570 //profile level
4571 switch (eLevel) {
4572 case OMX_VIDEO_AVCLevel1:
4573 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
4574 break;
4575 case OMX_VIDEO_AVCLevel1b:
4576 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
4577 break;
4578 case OMX_VIDEO_AVCLevel11:
4579 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
4580 break;
4581 case OMX_VIDEO_AVCLevel12:
4582 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
4583 break;
4584 case OMX_VIDEO_AVCLevel13:
4585 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
4586 break;
4587 case OMX_VIDEO_AVCLevel2:
4588 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
4589 break;
4590 case OMX_VIDEO_AVCLevel21:
4591 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
4592 break;
4593 case OMX_VIDEO_AVCLevel22:
4594 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
4595 break;
4596 case OMX_VIDEO_AVCLevel3:
4597 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
4598 break;
4599 case OMX_VIDEO_AVCLevel31:
4600 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
4601 break;
4602 case OMX_VIDEO_AVCLevel32:
4603 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
4604 break;
4605 case OMX_VIDEO_AVCLevel4:
4606 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
4607 break;
4608 case OMX_VIDEO_AVCLevel41:
4609 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
4610 break;
4611 case OMX_VIDEO_AVCLevel42:
4612 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
4613 break;
4614 case OMX_VIDEO_AVCLevel5:
4615 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
4616 break;
4617 case OMX_VIDEO_AVCLevel51:
4618 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
4619 break;
4620 case OMX_VIDEO_AVCLevel52:
4621 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4622 break;
4623 case OMX_VIDEO_AVCLevelMax:
4624 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4625 break;
4626 default :
4627 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
4628 requested_level.level);
4629 return false;
4630 break;
4631 }
4632 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4633 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
4634 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
4635 (unsigned int)eProfile);
4636 return false;
4637 }
4638 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
4639 m_profile_set = true;
4640 switch(eLevel) {
4641 case OMX_VIDEO_VP8Level_Version0:
4642 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
4643 break;
4644 case OMX_VIDEO_VP8Level_Version1:
4645 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
4646 break;
4647 default:
4648 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
4649 (unsigned int)eLevel);
4650 return false;
4651 break;
4652 }
4653 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4654 if (eProfile == OMX_VIDEO_HEVCProfileMain) {
4655 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
4656 } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
4657 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
4658 } else {
4659 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
4660 requested_profile.profile);
4661 return false;
4662 }
4663
4664 //profile level
4665 switch (eLevel) {
4666 case OMX_VIDEO_HEVCMainTierLevel1:
4667 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
4668 break;
4669 case OMX_VIDEO_HEVCHighTierLevel1:
4670 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
4671 break;
4672 case OMX_VIDEO_HEVCMainTierLevel2:
4673 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
4674 break;
4675 case OMX_VIDEO_HEVCHighTierLevel2:
4676 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
4677 break;
4678 case OMX_VIDEO_HEVCMainTierLevel21:
4679 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
4680 break;
4681 case OMX_VIDEO_HEVCHighTierLevel21:
4682 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
4683 break;
4684 case OMX_VIDEO_HEVCMainTierLevel3:
4685 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
4686 break;
4687 case OMX_VIDEO_HEVCHighTierLevel3:
4688 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
4689 break;
4690 case OMX_VIDEO_HEVCMainTierLevel31:
4691 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
4692 break;
4693 case OMX_VIDEO_HEVCHighTierLevel31:
4694 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
4695 break;
4696 case OMX_VIDEO_HEVCMainTierLevel4:
4697 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
4698 break;
4699 case OMX_VIDEO_HEVCHighTierLevel4:
4700 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
4701 break;
4702 case OMX_VIDEO_HEVCMainTierLevel41:
4703 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
4704 break;
4705 case OMX_VIDEO_HEVCHighTierLevel41:
4706 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
4707 break;
4708 case OMX_VIDEO_HEVCMainTierLevel5:
4709 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
4710 break;
4711 case OMX_VIDEO_HEVCHighTierLevel5:
4712 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
4713 break;
4714 case OMX_VIDEO_HEVCMainTierLevel51:
4715 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
4716 break;
4717 case OMX_VIDEO_HEVCHighTierLevel51:
4718 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
4719 break;
4720 case OMX_VIDEO_HEVCMainTierLevel52:
4721 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
4722 break;
4723 case OMX_VIDEO_HEVCHighTierLevel52:
4724 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
4725 break;
4726 case OMX_VIDEO_HEVCMainTierLevel6:
4727 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
4728 break;
4729 case OMX_VIDEO_HEVCHighTierLevel6:
4730 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
4731 break;
4732 case OMX_VIDEO_HEVCMainTierLevel61:
4733 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
4734 break;
4735 case OMX_VIDEO_HEVCHighTierLevel61:
4736 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
4737 break;
4738 default :
4739 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
4740 requested_level.level);
4741 return false;
4742 }
4743 }
4744
4745 if (!m_profile_set) {
4746 int rc;
4747 struct v4l2_control control;
4748
4749 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4750 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
4751 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4752 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
4753 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4754 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
4755 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4756 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
4757 } else {
4758 DEBUG_PRINT_ERROR("Wrong CODEC");
4759 return false;
4760 }
4761
4762 control.value = requested_profile.profile;
4763
4764 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4765 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4766
4767 if (rc) {
4768 DEBUG_PRINT_ERROR("Failed to set control");
4769 return false;
4770 }
4771
4772 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4773
4774 codec_profile.profile = control.value;
4775 m_profile_set = true;
4776 }
4777
4778 if (!m_level_set) {
4779 int rc;
4780 struct v4l2_control control;
4781
4782 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4783 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
4784 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4785 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
4786 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4787 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
4788 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4789 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
4790 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4791 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
4792 } else {
4793 DEBUG_PRINT_ERROR("Wrong CODEC");
4794 return false;
4795 }
4796
4797 control.value = requested_level.level;
4798
4799 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4800 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4801
4802 if (rc) {
4803 DEBUG_PRINT_ERROR("Failed to set control");
4804 return false;
4805 }
4806
4807 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4808
4809 profile_level.level = control.value;
4810 m_level_set = true;
4811 }
4812
4813 return true;
4814 }
4815
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)4816 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
4817 {
4818
4819 struct venc_voptimingcfg vop_timing_cfg;
4820
4821 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
4822 (unsigned int)TimeIncRes);
4823
4824 vop_timing_cfg.voptime_resolution = TimeIncRes;
4825
4826 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
4827 return true;
4828 }
4829
venc_set_intra_period_config(OMX_U32 nPFrames,OMX_U32 nBFrames)4830 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
4831 #if _ANDROID_
4832 // Android defines nBFrames as number of Bs between I OR P
4833 // Per the spec, nBFrames is number of Bs between I
4834 OMX_U32 nBs = nBFrames * (nPFrames + 1);
4835 DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
4836 nBFrames = nBs;
4837 #endif //_ANDROID_
4838 return venc_set_intra_period(nPFrames, nBFrames);
4839 }
4840
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)4841 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
4842 {
4843
4844 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
4845 int rc;
4846 struct v4l2_control control;
4847 int pframe = 0, bframe = 0;
4848
4849 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
4850 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
4851 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
4852 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
4853 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4854 nBFrames=0;
4855 }
4856
4857 if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
4858 DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
4859 return false;
4860 }
4861
4862 intra_period.num_pframes = nPFrames;
4863 intra_period.num_bframes = nBFrames;
4864
4865 if (!venc_calibrate_gop() && !is_thulium_v1)
4866 {
4867 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4868 return false;
4869 }
4870
4871 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4872 control.value = intra_period.num_pframes;
4873 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4874
4875 if (rc) {
4876 DEBUG_PRINT_ERROR("Failed to set control");
4877 return false;
4878 }
4879
4880 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4881
4882 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4883 control.value = intra_period.num_bframes;
4884 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4885 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4886
4887 if (rc) {
4888 DEBUG_PRINT_ERROR("Failed to set control");
4889 return false;
4890 }
4891
4892 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
4893
4894 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
4895 m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4896 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4897 control.value = 1;
4898
4899 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4900
4901 if (rc) {
4902 DEBUG_PRINT_ERROR("Failed to set control");
4903 return false;
4904 }
4905 idrperiod.idrperiod = 1;
4906 }
4907 return true;
4908 }
4909
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)4910 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
4911 {
4912 int rc = 0;
4913 struct v4l2_control control;
4914 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
4915 (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
4916
4917 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
4918 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
4919 return false;
4920 }
4921
4922 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
4923 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4924 return false;
4925 }
4926
4927 if (!intra_period.num_bframes)
4928 intra_period.num_pframes = nPFrames;
4929 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4930 control.value = nIDRPeriod;
4931
4932 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4933
4934 if (rc) {
4935 DEBUG_PRINT_ERROR("Failed to set control");
4936 return false;
4937 }
4938
4939 idrperiod.idrperiod = nIDRPeriod;
4940 return true;
4941 }
4942
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)4943 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
4944 {
4945 int rc = 0;
4946 struct v4l2_control control;
4947
4948 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
4949
4950 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
4951 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
4952
4953 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
4954 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4955
4956 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4957 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4958
4959 if (rc) {
4960 DEBUG_PRINT_ERROR("Failed to set control");
4961 return false;
4962 }
4963
4964 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4965 entropy.longentropysel = control.value;
4966
4967 if (i_cabac_level == 0) {
4968 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
4969 } else if (i_cabac_level == 1) {
4970 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
4971 } else if (i_cabac_level == 2) {
4972 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
4973 }
4974
4975 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
4976 //control.value = entropy_cfg.cabacmodel;
4977 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4978 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4979
4980 if (rc) {
4981 DEBUG_PRINT_ERROR("Failed to set control");
4982 return false;
4983 }
4984
4985 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4986 entropy.cabacmodel=control.value;
4987 } else if (!enable) {
4988 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
4989 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4990 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4991 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4992
4993 if (rc) {
4994 DEBUG_PRINT_ERROR("Failed to set control");
4995 return false;
4996 }
4997
4998 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4999 entropy.longentropysel=control.value;
5000 } else {
5001 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
5002 return false;
5003 }
5004
5005 return true;
5006 }
5007
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)5008 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
5009 {
5010 int rc;
5011 struct v4l2_control control;
5012 bool status = true;
5013
5014 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) {
5015 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
5016 } else {
5017 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5018 }
5019
5020 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5021 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5022 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5023
5024 if (rc) {
5025 DEBUG_PRINT_ERROR("Failed to set control");
5026 return false;
5027 }
5028
5029 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5030 multislice.mslice_mode=control.value;
5031
5032 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
5033
5034 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
5035 control.value = nSlicesize;
5036 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
5037 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5038
5039 if (rc) {
5040 DEBUG_PRINT_ERROR("Failed to set control");
5041 return false;
5042 }
5043
5044 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5045 multislice.mslice_size=control.value;
5046
5047 }
5048
5049 return status;
5050 }
5051
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)5052 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
5053 {
5054 bool status = true;
5055 int rc;
5056 struct v4l2_control control_mode,control_mbs;
5057 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
5058
5059 // There is no disabled mode. Disabled mode is indicated by a 0 count.
5060 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
5061 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
5062 return status;
5063 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
5064 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5065 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
5066 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
5067 control_mbs.value=irMBs;
5068 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
5069 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5070 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
5071 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5072 control_mbs.value=irMBs;
5073 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
5074 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5075 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
5076 } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
5077 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5078 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
5079 control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5080 control_mbs.value = irMBs;
5081 } else {
5082 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
5083 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
5084 return false;
5085 }
5086
5087 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
5088 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
5089
5090 if (rc) {
5091 DEBUG_PRINT_ERROR("Failed to set control");
5092 return false;
5093 }
5094
5095 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
5096
5097 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
5098 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
5099
5100 if (rc) {
5101 DEBUG_PRINT_ERROR("Failed to set control");
5102 return false;
5103 }
5104
5105 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
5106
5107 intra_refresh.irmode = control_mode.value;
5108 intra_refresh.mbcount = control_mbs.value;
5109
5110 return status;
5111 }
5112
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)5113 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
5114 {
5115 bool status = true;
5116 struct venc_headerextension hec_cfg;
5117 struct venc_multiclicecfg multislice_cfg;
5118 int rc;
5119 OMX_U32 resynchMarkerSpacingBytes = 0;
5120 struct v4l2_control control;
5121
5122 memset(&control, 0, sizeof(control));
5123
5124 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5125 if (error_resilience->bEnableHEC) {
5126 hec_cfg.header_extension = 1;
5127 } else {
5128 hec_cfg.header_extension = 0;
5129 }
5130
5131 hec.header_extension = error_resilience->bEnableHEC;
5132 }
5133
5134 if (error_resilience->bEnableRVLC) {
5135 DEBUG_PRINT_ERROR("RVLC is not Supported");
5136 return false;
5137 }
5138
5139 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5140 (error_resilience->bEnableDataPartitioning)) {
5141 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
5142 return false;
5143 }
5144
5145 if (error_resilience->nResynchMarkerSpacing) {
5146 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
5147 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
5148 }
5149 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5150 (error_resilience->nResynchMarkerSpacing)) {
5151 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
5152 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5153 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5154 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
5155 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
5156 error_resilience->bEnableDataPartitioning) {
5157 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
5158 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5159 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5160 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
5161 } else {
5162 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
5163 multislice_cfg.mslice_size = 0;
5164 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5165 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5166 }
5167
5168 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
5169 multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
5170 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5171 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5172
5173 if (rc) {
5174 DEBUG_PRINT_ERROR("Failed to set Slice mode control");
5175 return false;
5176 }
5177
5178 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5179 multislice.mslice_mode=control.value;
5180
5181 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
5182 control.value = resynchMarkerSpacingBytes;
5183 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5184
5185 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5186
5187 if (rc) {
5188 DEBUG_PRINT_ERROR("Failed to set MAX MB control");
5189 return false;
5190 }
5191
5192 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5193 multislice.mslice_mode = multislice_cfg.mslice_mode;
5194 multislice.mslice_size = multislice_cfg.mslice_size;
5195 return status;
5196 }
5197
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)5198 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
5199 {
5200 int rc;
5201 struct v4l2_control control;
5202 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
5203
5204 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
5205 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
5206 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
5207 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
5208 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
5209 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
5210 }
5211
5212 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5213 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5214
5215 if (rc) {
5216 return false;
5217 }
5218
5219 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5220
5221 dbkfilter.db_mode=control.value;
5222
5223 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
5224 control.value=0;
5225
5226 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5227 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5228
5229 if (rc) {
5230 return false;
5231 }
5232
5233 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5234 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
5235 control.value=0;
5236 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5237 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5238
5239 if (rc) {
5240 return false;
5241 }
5242
5243 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5244
5245
5246 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
5247 return true;
5248 }
5249
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)5250 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
5251 {
5252 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
5253 (unsigned int)nTargetBitrate);
5254 struct v4l2_control control;
5255 int rc = 0;
5256 control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
5257 control.value = nTargetBitrate;
5258
5259 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5260 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5261
5262 if (rc) {
5263 DEBUG_PRINT_ERROR("Failed to set control");
5264 return false;
5265 }
5266
5267 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5268
5269
5270 m_sVenc_cfg.targetbitrate = control.value;
5271 bitrate.target_bitrate = control.value;
5272
5273 if (!config) {
5274 m_level_set = false;
5275
5276 if (venc_set_profile_level(0, 0)) {
5277 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
5278 }
5279 }
5280
5281 // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
5282 // has been specified
5283 if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
5284 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
5285 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5286
5287 DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
5288 for (OMX_U32 i = 0; i < numLayers; ++i) {
5289 layerBitrates[i] =
5290 (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
5291 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
5292 i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
5293 layerBitrates[i], bitrate.target_bitrate);
5294 }
5295 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
5296 return false;
5297 }
5298 }
5299
5300 return true;
5301 }
5302
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)5303 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
5304 {
5305 struct v4l2_streamparm parm;
5306 int rc = 0;
5307 struct venc_framerate frame_rate_cfg;
5308 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
5309 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5310 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
5311 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
5312
5313 if (frame_rate_cfg.fps_numerator > 0)
5314 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
5315
5316 if (rc) {
5317 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
5318 return false;
5319 }
5320
5321 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
5322 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
5323
5324 if (!config) {
5325 m_level_set = false;
5326
5327 if (venc_set_profile_level(0, 0)) {
5328 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
5329 }
5330 }
5331
5332 return true;
5333 }
5334
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)5335 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
5336 {
5337 struct v4l2_format fmt;
5338 int color_space = 0;
5339 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
5340
5341 switch ((int)color_format) {
5342 case OMX_COLOR_FormatYUV420SemiPlanar:
5343 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
5344 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
5345 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5346 break;
5347 case QOMX_COLOR_FormatYVU420SemiPlanar:
5348 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
5349 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5350 break;
5351 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
5352 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
5353 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5354 break;
5355 case QOMX_COLOR_Format32bitRGBA8888:
5356 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
5357 break;
5358 case QOMX_COLOR_Format32bitRGBA8888Compressed:
5359 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
5360 break;
5361 default:
5362 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
5363 m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
5364 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5365 DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
5366 break;
5367 }
5368
5369 memset(&fmt, 0, sizeof(fmt));
5370 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5371 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
5372 fmt.fmt.pix_mp.colorspace = color_space;
5373 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
5374 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
5375
5376 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5377 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
5378 return false;
5379 }
5380
5381 return true;
5382 }
5383
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)5384 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
5385 {
5386 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
5387
5388 if (intra_vop_refresh == OMX_TRUE) {
5389 struct v4l2_control control;
5390 int rc;
5391 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
5392 control.value = 1;
5393 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5394 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5395
5396 if (rc) {
5397 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
5398 return false;
5399 }
5400
5401 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5402 } else {
5403 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
5404 }
5405
5406 return true;
5407 }
5408
venc_set_deinterlace(OMX_U32 enable)5409 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
5410 {
5411 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
5412 struct v4l2_control control;
5413 int rc;
5414 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
5415 if (enable)
5416 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5417 else
5418 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5419
5420 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5421 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5422 if (rc) {
5423 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
5424 return false;
5425 }
5426 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5427 deinterlace_enabled = true;
5428 return true;
5429 }
5430
venc_calibrate_gop()5431 bool venc_dev::venc_calibrate_gop()
5432 {
5433 int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
5434 int num_sub_gops_in_a_gop;
5435 nPframes = intra_period.num_pframes;
5436 nBframes = intra_period.num_bframes;
5437 nLayers = hier_layers.numlayers;
5438 if (temporal_layers_config.nPLayers) {
5439 nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5440 }
5441
5442 if (!nPframes && nLayers) {
5443 DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
5444 return false;
5445 }
5446
5447 if (nLayers > 1) { /*Multi-layer encoding*/
5448 sub_gop_size = 1 << (nLayers - 1);
5449 /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
5450 * below calculations we are ignoring +1 . Ignoring +1 in below
5451 * calculations is not a mistake but intentional.
5452 */
5453 gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
5454 num_sub_gops_in_a_gop = gop_size/sub_gop_size;
5455 if (nBframes) { /*Hier-B case*/
5456 /*
5457 * Frame Type--> I B B B P B B B P I B B P ...
5458 * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ...
5459 * nPframes = 2, nBframes = 6, nLayers = 3
5460 *
5461 * Intention is to keep the intraperiod as close as possible to what is desired
5462 * by the client while adjusting nPframes and nBframes to meet other constraints.
5463 * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2
5464 * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
5465 *
5466 * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
5467 * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
5468 */
5469 nPframes = num_sub_gops_in_a_gop;
5470 nBframes = gop_size - nPframes;
5471 } else { /*Hier-P case*/
5472 /*
5473 * Frame Type--> I P P P P P P P I P P P P ...
5474 * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ...
5475 * nPframes = 7, nBframes = 0, nLayers = 3
5476 *
5477 * Intention is to keep the intraperiod as close as possible to what is desired
5478 * by the client while adjusting nPframes and nBframes to meet other constraints.
5479 * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
5480 * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
5481 *
5482 * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
5483 * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
5484 */
5485 nPframes = gop_size - 1;
5486 }
5487 } else { /*Single-layer encoding*/
5488 if (nBframes) {
5489 /* I P B B B P B B B P B B B I P B B...
5490 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...
5491 * nPframes = 3, nBframes = 9, nLayers = 0
5492 *
5493 * ratio is rounded,
5494 * eg1: nPframes = 9, nBframes = 11 => ratio = 1
5495 * eg2: nPframes = 9, nBframes = 16 => ratio = 2
5496 */
5497 ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
5498 nBframes = ratio * nPframes;
5499 }
5500 }
5501 DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
5502 intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
5503 intra_period.num_pframes = nPframes;
5504 intra_period.num_bframes = nBframes;
5505 hier_layers.numlayers = nLayers;
5506 return true;
5507 }
5508
venc_set_bitrate_type(OMX_U32 type)5509 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
5510 {
5511 struct v4l2_control control;
5512 int rc = 0;
5513 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
5514 control.value = type;
5515 DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
5516 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5517 if (rc) {
5518 DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
5519 bitrate_type_string(type));
5520 return false;
5521 }
5522 return true;
5523 }
5524
venc_set_layer_bitrates(OMX_U32 * layerBitrate,OMX_U32 numLayers)5525 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
5526 {
5527 DEBUG_PRINT_LOW("venc_set_layer_bitrates");
5528 struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
5529 struct v4l2_ext_controls controls;
5530 int rc = 0;
5531 OMX_U32 i;
5532
5533 if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
5534 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
5535 return false;
5536 }
5537
5538 for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
5539 if (!layerBitrate[i]) {
5540 DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
5541 return false;
5542 } else {
5543 ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
5544 ctrl[i].value = layerBitrate[i];
5545 }
5546 }
5547 controls.count = numLayers;
5548 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5549 controls.controls = ctrl;
5550
5551 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5552 if (rc) {
5553 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
5554 return false;
5555 }
5556
5557 DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
5558 return true;
5559 }
5560
venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE * hhp)5561 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
5562 {
5563 DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
5564 struct v4l2_control control;
5565 int rc;
5566
5567 if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
5568 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5569 return false;
5570 }
5571
5572 if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
5573 DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
5574 return false;
5575 }
5576 if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
5577 DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
5578 return false;
5579 }
5580
5581 hier_layers.numlayers = hhp->nHpLayers;
5582 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5583 hier_layers.hier_mode = HIER_P_HYBRID;
5584 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5585 hier_layers.hier_mode = HIER_P;
5586 }
5587 if (venc_calibrate_gop()) {
5588 // Update the driver with the new nPframes and nBframes
5589 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
5590 control.value = intra_period.num_pframes;
5591 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5592 if (rc) {
5593 DEBUG_PRINT_ERROR("Failed to set control");
5594 return false;
5595 }
5596
5597 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
5598 control.value = intra_period.num_bframes;
5599 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5600 if (rc) {
5601 DEBUG_PRINT_ERROR("Failed to set control");
5602 return false;
5603 }
5604 DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
5605 intra_period.num_pframes, intra_period.num_bframes);
5606 } else {
5607 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5608 return false;
5609 }
5610 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5611 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
5612 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5613 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
5614 }
5615 control.value = hhp->nHpLayers - 1;
5616
5617 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
5618 control.id, control.value);
5619
5620 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5621 if (rc) {
5622 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
5623 return false;
5624 }
5625
5626 DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
5627 control.id, control.value);
5628 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5629 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
5630 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
5631 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5632 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5633 return false;
5634 }
5635 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5636 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
5637 control.value = hhp->nHpLayers - 1;
5638 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5639 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5640 return false;
5641 }
5642 } else {
5643 DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
5644 return false;
5645 }
5646
5647 if(venc_set_session_qp_range (hhp->nMinQuantizer,
5648 hhp->nMaxQuantizer) == false) {
5649 DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
5650 (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
5651 return false;
5652 } else {
5653 session_qp_values.minqp = hhp->nMinQuantizer;
5654 session_qp_values.maxqp = hhp->nMaxQuantizer;
5655 }
5656
5657 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
5658 for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
5659 layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
5660 hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
5661 DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
5662 }
5663 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
5664 DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
5665 hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
5666 hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
5667 hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
5668 return false;
5669 }
5670 hybrid_hp.nHpLayers = hhp->nHpLayers;
5671
5672 // Set this or else the layer0 bitrate will be overwritten by
5673 // default value in component
5674 m_sVenc_cfg.targetbitrate = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
5675 hybrid_hp.nHpLayers = hhp->nHpLayers;
5676 hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
5677 hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
5678 hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
5679 return true;
5680 }
5681
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)5682 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
5683 {
5684 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
5685 struct v4l2_ext_control ctrl[2];
5686 struct v4l2_ext_controls controls;
5687 int rc;
5688
5689 if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
5690 DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
5691 return false;
5692 }
5693
5694 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
5695 if (enable)
5696 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
5697 else
5698 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
5699
5700 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
5701 if (enable && count > 0)
5702 ctrl[1].value = count;
5703 else if (enable)
5704 ctrl[1].value = 1;
5705 else
5706 ctrl[1].value = 0;
5707
5708 controls.count = 2;
5709 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5710 controls.controls = ctrl;
5711
5712 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
5713 controls.controls[0].id, controls.controls[0].value,
5714 controls.controls[1].id, controls.controls[1].value);
5715
5716 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5717 if (rc) {
5718 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5719 return false;
5720 }
5721 ltrinfo.enabled = enable;
5722 ltrinfo.count = count;
5723
5724 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
5725 controls.controls[0].id, controls.controls[0].value,
5726 controls.controls[1].id, controls.controls[1].value);
5727
5728 if (!venc_set_profile_level(0, 0)) {
5729 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
5730 __func__);
5731 } else {
5732 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
5733 __func__, codec_profile.profile, profile_level.level);
5734 }
5735
5736 return true;
5737 }
5738
venc_set_useltr(OMX_U32 frameIdx)5739 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
5740 {
5741 DEBUG_PRINT_LOW("venc_use_goldenframe");
5742 int rc = true;
5743 struct v4l2_control control;
5744
5745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
5746 control.value = frameIdx;
5747
5748 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5749 if (rc) {
5750 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
5751 return false;
5752 }
5753
5754 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5755 control.id, control.value);
5756 return true;
5757 }
5758
venc_set_markltr(OMX_U32 frameIdx)5759 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
5760 {
5761 DEBUG_PRINT_LOW("venc_set_goldenframe");
5762 int rc = true;
5763 struct v4l2_control control;
5764
5765 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
5766 control.value = frameIdx;
5767
5768 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5769 if (rc) {
5770 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5771 return false;
5772 }
5773
5774 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5775 control.id, control.value);
5776 return true;
5777 }
5778
venc_set_vpe_rotation(OMX_S32 rotation_angle)5779 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
5780 {
5781 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
5782 struct v4l2_control control;
5783 int rc;
5784 struct v4l2_format fmt;
5785 struct v4l2_requestbuffers bufreq;
5786
5787 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
5788 if (rotation_angle == 0)
5789 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
5790 else if (rotation_angle == 90)
5791 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
5792 else if (rotation_angle == 180)
5793 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
5794 else if (rotation_angle == 270)
5795 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
5796 else {
5797 DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
5798 return false;
5799 }
5800
5801 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5802 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5803 if (rc) {
5804 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
5805 return false;
5806 }
5807 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5808
5809 memset(&fmt, 0, sizeof(fmt));
5810 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5811 if (rotation_angle == 90 || rotation_angle == 270) {
5812 OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
5813 OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
5814 m_sVenc_cfg.dvs_height = nHeight;
5815 m_sVenc_cfg.dvs_width = nWidth;
5816 DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
5817 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
5818 }
5819
5820 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
5821 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
5822 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
5823 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5824 DEBUG_PRINT_ERROR("Failed to set format on capture port");
5825 return false;
5826 }
5827
5828 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
5829 bufreq.memory = V4L2_MEMORY_USERPTR;
5830 bufreq.count = m_sOutput_buff_property.actualcount;
5831 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5832 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
5833 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
5834 return false;
5835 }
5836 if (bufreq.count >= m_sOutput_buff_property.mincount)
5837 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
5838
5839 return true;
5840 }
5841
venc_set_searchrange()5842 bool venc_dev::venc_set_searchrange()
5843 {
5844 DEBUG_PRINT_LOW("venc_set_searchrange");
5845 struct v4l2_control control;
5846 struct v4l2_ext_control ctrl[6];
5847 struct v4l2_ext_controls controls;
5848 int rc;
5849
5850 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5851 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5852 ctrl[0].value = 16;
5853 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5854 ctrl[1].value = 4;
5855 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5856 ctrl[2].value = 16;
5857 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5858 ctrl[3].value = 4;
5859 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5860 ctrl[4].value = 12;
5861 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5862 ctrl[5].value = 4;
5863 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
5864 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
5865 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5866 ctrl[0].value = 16;
5867 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5868 ctrl[1].value = 4;
5869 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5870 ctrl[2].value = 16;
5871 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5872 ctrl[3].value = 4;
5873 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5874 ctrl[4].value = 12;
5875 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5876 ctrl[5].value = 4;
5877 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5878 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5879 ctrl[0].value = 4;
5880 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5881 ctrl[1].value = 4;
5882 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5883 ctrl[2].value = 4;
5884 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5885 ctrl[3].value = 4;
5886 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5887 ctrl[4].value = 4;
5888 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5889 ctrl[5].value = 4;
5890 } else {
5891 DEBUG_PRINT_ERROR("Invalid codec type");
5892 return false;
5893 }
5894 controls.count = 6;
5895 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5896 controls.controls = ctrl;
5897
5898 DEBUG_PRINT_LOW(" Calling IOCTL set control for"
5899 "id=%x, val=%d id=%x, val=%d"
5900 "id=%x, val=%d id=%x, val=%d"
5901 "id=%x, val=%d id=%x, val=%d",
5902 controls.controls[0].id, controls.controls[0].value,
5903 controls.controls[1].id, controls.controls[1].value,
5904 controls.controls[2].id, controls.controls[2].value,
5905 controls.controls[3].id, controls.controls[3].value,
5906 controls.controls[4].id, controls.controls[4].value,
5907 controls.controls[5].id, controls.controls[5].value);
5908
5909 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5910 if (rc) {
5911 DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
5912 return false;
5913 }
5914 return true;
5915 }
5916
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)5917 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
5918 {
5919 bool status = true;
5920 struct v4l2_control control;
5921 int rc = 0;
5922 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
5923
5924 switch (eControlRate) {
5925 case OMX_Video_ControlRateDisable:
5926 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
5927 break;
5928 case OMX_Video_ControlRateVariableSkipFrames:
5929 (supported_rc_modes & RC_VBR_VFR) ?
5930 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
5931 status = false;
5932 break;
5933 case OMX_Video_ControlRateVariable:
5934 (supported_rc_modes & RC_VBR_CFR) ?
5935 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
5936 status = false;
5937 break;
5938 case OMX_Video_ControlRateConstantSkipFrames:
5939 (supported_rc_modes & RC_CBR_VFR) ?
5940 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
5941 status = false;
5942 break;
5943 case OMX_Video_ControlRateConstant:
5944 (supported_rc_modes & RC_CBR_CFR) ?
5945 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
5946 status = false;
5947 break;
5948 default:
5949 status = false;
5950 break;
5951 }
5952
5953 if (status) {
5954
5955 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5956 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5957
5958 if (rc) {
5959 DEBUG_PRINT_ERROR("Failed to set control");
5960 return false;
5961 }
5962
5963 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5964
5965 rate_ctrl.rcmode = control.value;
5966 }
5967
5968 #ifdef _VQZIP_
5969 if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
5970 && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5971 /* Enable VQZIP SEI by default for camcorder RC modes */
5972
5973 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
5974 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
5975 DEBUG_PRINT_HIGH("Set VQZIP SEI:");
5976 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
5977 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
5978 }
5979 }
5980 #endif //_VQZIP_
5981
5982 return status;
5983 }
5984
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)5985 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
5986 {
5987 bool status = true;
5988 struct v4l2_control control;
5989 int rc = 0;
5990 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
5991
5992 switch (ePerfLevel) {
5993 case OMX_QCOM_PerfLevelNominal:
5994 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
5995 break;
5996 case OMX_QCOM_PerfLevelTurbo:
5997 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
5998 break;
5999 default:
6000 status = false;
6001 break;
6002 }
6003
6004 if (status) {
6005 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6006 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6007
6008 if (rc) {
6009 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
6010 return false;
6011 }
6012
6013 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6014 }
6015 return status;
6016 }
6017
venc_set_perf_mode(OMX_U32 mode)6018 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
6019 {
6020 struct v4l2_control control;
6021 if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
6022 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
6023 control.value = mode;
6024 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6025 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6026 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6027 return false;
6028 }
6029 return true;
6030 } else {
6031 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
6032 return false;
6033 }
6034 }
6035
venc_set_qp(OMX_U32 nQp)6036 bool venc_dev::venc_set_qp(OMX_U32 nQp)
6037 {
6038 struct v4l2_control control;
6039 if (nQp) {
6040 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
6041 control.value = nQp;
6042 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6043 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6044 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6045 return false;
6046 }
6047 } else {
6048 DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
6049 return false;
6050 }
6051 return true;
6052 }
6053
venc_set_aspectratio(void * nSar)6054 bool venc_dev::venc_set_aspectratio(void *nSar)
6055 {
6056 int rc;
6057 struct v4l2_control control;
6058 struct v4l2_ext_control ctrl[2];
6059 struct v4l2_ext_controls controls;
6060 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
6061
6062 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
6063
6064 ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
6065 ctrl[0].value = sar->nSARWidth;
6066 ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
6067 ctrl[1].value = sar->nSARHeight;
6068
6069 controls.count = 2;
6070 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
6071 controls.controls = ctrl;
6072
6073 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
6074 controls.controls[0].id, controls.controls[0].value,
6075 controls.controls[1].id, controls.controls[1].value);
6076
6077 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
6078 if (rc) {
6079 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
6080 return false;
6081 }
6082
6083 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
6084 controls.controls[0].id, controls.controls[0].value,
6085 controls.controls[1].id, controls.controls[1].value);
6086 return true;
6087 }
6088
venc_set_hierp_layers(OMX_U32 hierp_layers)6089 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
6090 {
6091 struct v4l2_control control;
6092 if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
6093 (hierp_layers <= hier_layers.numlayers)) {
6094 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6095 control.value = hierp_layers - 1;
6096 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
6097 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6098 DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
6099 return false;
6100 }
6101 return true;
6102 } else {
6103 DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
6104 hierp_layers);
6105 return false;
6106 }
6107 }
6108
venc_set_baselayerid(OMX_U32 baseid)6109 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
6110 {
6111 struct v4l2_control control;
6112 if (hier_layers.hier_mode == HIER_P) {
6113 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
6114 control.value = baseid;
6115 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6116 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6117 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6118 return false;
6119 }
6120 return true;
6121 } else {
6122 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
6123 hier_layers.hier_mode);
6124 return false;
6125 }
6126 }
6127
venc_set_vui_timing_info(OMX_BOOL enable)6128 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
6129 {
6130 struct v4l2_control control;
6131 int rc = 0;
6132 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
6133
6134 if (enable)
6135 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
6136 else
6137 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
6138
6139 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
6140 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6141 if (rc) {
6142 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
6143 return false;
6144 }
6145 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
6146 return true;
6147 }
6148
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)6149 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
6150 {
6151 struct v4l2_control control;
6152 int rc = 0;
6153 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
6154 control.value = nPeakBitrate;
6155
6156 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
6157
6158 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6159 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6160
6161 if (rc) {
6162 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
6163 return false;
6164 }
6165
6166 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6167
6168 return true;
6169 }
6170
venc_set_vpx_error_resilience(OMX_BOOL enable)6171 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
6172 {
6173 struct v4l2_control control;
6174 int rc = 0;
6175 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
6176
6177 if (enable)
6178 control.value = 1;
6179 else
6180 control.value = 0;
6181
6182 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
6183
6184 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6185
6186 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6187 if (rc) {
6188 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
6189 return false;
6190 }
6191 vpx_err_resilience.enable = 1;
6192 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6193 return true;
6194 }
6195
venc_set_priority(OMX_U32 priority)6196 bool venc_dev::venc_set_priority(OMX_U32 priority) {
6197 struct v4l2_control control;
6198
6199 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
6200 if (priority == 0)
6201 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
6202 else
6203 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
6204
6205 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6206 DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
6207 priority == 0 ? "ENABLE" : "DISABLE");
6208 return false;
6209 }
6210 return true;
6211 }
6212
venc_set_operatingrate(OMX_U32 rate)6213 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
6214 struct v4l2_control control;
6215
6216 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
6217 control.value = rate;
6218
6219 DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
6220 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6221
6222 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6223 hw_overload = errno == EBUSY;
6224 DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
6225 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
6226 return false;
6227 }
6228 operating_rate = rate;
6229 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16);
6230 return true;
6231 }
6232
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)6233 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
6234 char *userptr;
6235 int fd;
6236 unsigned offset;
6237 ssize_t size;
6238 struct msm_vidc_roi_qp_payload *roiData;
6239 if (!roiInfo) {
6240 DEBUG_PRINT_ERROR("No ROI info present");
6241 return false;
6242 }
6243 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
6244 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
6245 DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
6246 return false;
6247 }
6248
6249 venc_roiqp_log_buffers(roiInfo);
6250 mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
6251 if (!userptr || size < roiInfo->nRoiMBInfoSize) {
6252 DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
6253 return false;
6254 }
6255
6256 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
6257 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
6258 data->nVersion.nVersion = OMX_SPEC_VERSION;
6259 data->nPortIndex = 0;
6260 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
6261 data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
6262
6263 roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
6264 roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
6265 roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
6266 roiData->b_roi_info = roiInfo->bUseRoiInfo;
6267 roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
6268 memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
6269
6270 data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
6271 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
6272 data->nVersion.nVersion = OMX_SPEC_VERSION;
6273 data->nPortIndex = 0;
6274 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
6275 data->nDataSize = 0;
6276 return true;
6277 }
6278
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)6279 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
6280 OMX_U32 *nMaxBLayers) {
6281
6282 // no B-layers for all cases
6283 temporal_layers_config.nMaxBLayers = 0;
6284 temporal_layers_config.nMaxLayers = 1;
6285
6286 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6287 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6288 temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
6289 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6290 temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
6291 }
6292
6293 *nMaxLayers = temporal_layers_config.nMaxLayers;
6294 *nMaxBLayers = temporal_layers_config.nMaxBLayers;
6295 return true;
6296 }
6297
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)6298 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
6299 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
6300
6301 if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6302 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
6303 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
6304 DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
6305 return OMX_ErrorUnsupportedSetting;
6306 }
6307
6308 if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
6309 (pTemporalParams->nBLayerCountActual != 0 ||
6310 pTemporalParams->nPLayerCountActual != 1)) {
6311 return OMX_ErrorBadParameter;
6312 } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
6313 pTemporalParams->nPLayerCountActual < 1) {
6314 return OMX_ErrorBadParameter;
6315 }
6316
6317 if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
6318 DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
6319 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
6320 return OMX_ErrorBadParameter;
6321 } else if (pTemporalParams->nPLayerCountActual >
6322 temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
6323 DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
6324 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
6325 temporal_layers_config.nMaxLayers);
6326 return OMX_ErrorBadParameter;
6327 }
6328
6329 // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
6330 // use hybrid-HP for best results
6331 bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
6332 bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
6333 bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
6334
6335 // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
6336 bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
6337
6338 DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
6339 rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
6340
6341 if (bUseHybridMode &&
6342 !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
6343 pTemporalParams->nBLayerCountActual,
6344 0 /* LTR count */, (int) HIER_P_HYBRID)) {
6345 bUseHybridMode = false;
6346 DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
6347 }
6348
6349 if (intra_period.num_bframes) {
6350 DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
6351 return OMX_ErrorUnsupportedSetting;
6352 }
6353
6354 if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
6355 DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
6356 intra_period.num_pframes, intra_period.num_bframes);
6357 return OMX_ErrorUnsupportedSetting;
6358 }
6359
6360 struct v4l2_control control;
6361 // Num enhancements layers does not include the base-layer
6362 control.value = pTemporalParams->nPLayerCountActual - 1;
6363
6364 if (bUseHybridMode) {
6365 DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
6366 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6367 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6368 bUseHybridMode = false;
6369 DEBUG_PRINT_ERROR("Failed to set hybrid HP");
6370 } else {
6371 // Disable normal HP if Hybrid mode is being enabled
6372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6373 control.value = 0;
6374 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6375 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6376 return OMX_ErrorUnsupportedSetting;
6377 }
6378 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6379 control.value = 0;
6380 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6381 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
6382 return OMX_ErrorUnsupportedSetting;
6383 }
6384 }
6385 }
6386
6387 if (!bUseHybridMode) {
6388
6389 // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
6390 if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
6391 DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
6392 return OMX_ErrorUnsupportedSetting;
6393 }
6394
6395 DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
6396 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6397 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6398 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
6399 return OMX_ErrorUnsupportedSetting;
6400 }
6401
6402 // configure max layers for a session.. Okay to use current num-layers as max
6403 // since we do not plan to support dynamic changes to number of layers
6404 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6405 control.value = pTemporalParams->nPLayerCountActual - 1;
6406 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6407 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6408 return OMX_ErrorUnsupportedSetting;
6409
6410 } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
6411 // Disable hybrid mode if it was enabled already
6412 DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
6413 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6414 control.value = 0;
6415 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6416 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
6417 return OMX_ErrorUnsupportedSetting;
6418 }
6419 }
6420 }
6421
6422 // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
6423 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6424 DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
6425 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
6426 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
6427 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6428 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
6429 return OMX_ErrorUnsupportedSetting;
6430 }
6431 }
6432
6433 temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
6434 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
6435 temporal_layers_config.nBLayers = 0;
6436
6437 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
6438 if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
6439 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
6440 return OMX_ErrorNone;
6441 }
6442 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
6443
6444 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
6445 numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
6446
6447 OMX_U32 i = 0;
6448 for (; i < numLayers; ++i) {
6449 OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
6450 OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
6451 if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
6452 DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
6453 return OMX_ErrorBadParameter;
6454 } else {
6455 layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
6456 temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
6457 temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
6458 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
6459 i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
6460 }
6461 }
6462
6463 temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
6464
6465 // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
6466 if (bitrate.target_bitrate > 0) {
6467 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
6468 return OMX_ErrorUnsupportedSetting;
6469 }
6470 } else {
6471 DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
6472 }
6473
6474 return OMX_ErrorNone;
6475 }
6476
venc_set_temporal_layers_internal()6477 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
6478 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
6479 memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
6480
6481 if (!temporal_layers_config.nPLayers) {
6482 return OMX_ErrorNone;
6483 }
6484 pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6485 pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
6486 pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
6487 pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6488 pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
6489 pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
6490 pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
6491 if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
6492 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
6493 pTemporalParams.nBitrateRatios[i] =
6494 temporal_layers_config.nTemporalLayerBitrateRatio[i];
6495 }
6496 }
6497 return venc_set_temporal_layers(&pTemporalParams);
6498 }
6499
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6500 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
6501 {
6502 bool status = true;
6503
6504 if (eProfile == NULL || eLevel == NULL) {
6505 return false;
6506 }
6507
6508 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6509 switch (codec_profile.profile) {
6510 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6511 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6512 break;
6513 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6514 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6515 break;
6516 default:
6517 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
6518 status = false;
6519 break;
6520 }
6521
6522 if (!status) {
6523 return status;
6524 }
6525
6526 //profile level
6527 switch (profile_level.level) {
6528 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
6529 *eLevel = OMX_VIDEO_MPEG4Level0;
6530 break;
6531 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
6532 *eLevel = OMX_VIDEO_MPEG4Level0b;
6533 break;
6534 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
6535 *eLevel = OMX_VIDEO_MPEG4Level1;
6536 break;
6537 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
6538 *eLevel = OMX_VIDEO_MPEG4Level2;
6539 break;
6540 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
6541 *eLevel = OMX_VIDEO_MPEG4Level3;
6542 break;
6543 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
6544 *eLevel = OMX_VIDEO_MPEG4Level4;
6545 break;
6546 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
6547 *eLevel = OMX_VIDEO_MPEG4Level5;
6548 break;
6549 default:
6550 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6551 status = false;
6552 break;
6553 }
6554 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6555 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
6556 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6557 } else {
6558 *eProfile = OMX_VIDEO_H263ProfileMax;
6559 return false;
6560 }
6561
6562 switch (profile_level.level) {
6563 case VEN_LEVEL_H263_10:
6564 *eLevel = OMX_VIDEO_H263Level10;
6565 break;
6566 case VEN_LEVEL_H263_20:
6567 *eLevel = OMX_VIDEO_H263Level20;
6568 break;
6569 case VEN_LEVEL_H263_30:
6570 *eLevel = OMX_VIDEO_H263Level30;
6571 break;
6572 case VEN_LEVEL_H263_40:
6573 *eLevel = OMX_VIDEO_H263Level40;
6574 break;
6575 case VEN_LEVEL_H263_45:
6576 *eLevel = OMX_VIDEO_H263Level45;
6577 break;
6578 case VEN_LEVEL_H263_50:
6579 *eLevel = OMX_VIDEO_H263Level50;
6580 break;
6581 case VEN_LEVEL_H263_60:
6582 *eLevel = OMX_VIDEO_H263Level60;
6583 break;
6584 case VEN_LEVEL_H263_70:
6585 *eLevel = OMX_VIDEO_H263Level70;
6586 break;
6587 default:
6588 *eLevel = OMX_VIDEO_H263LevelMax;
6589 status = false;
6590 break;
6591 }
6592 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6593 switch (codec_profile.profile) {
6594 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6595 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6596 break;
6597 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6598 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6599 break;
6600 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6601 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6602 break;
6603 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6604 *eProfile = OMX_VIDEO_AVCProfileMain;
6605 break;
6606 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6607 *eProfile = OMX_VIDEO_AVCProfileHigh;
6608 break;
6609 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6610 *eProfile = OMX_VIDEO_AVCProfileExtended;
6611 break;
6612 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6613 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6614 break;
6615 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6616 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6617 break;
6618 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6619 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6620 break;
6621 default:
6622 *eProfile = OMX_VIDEO_AVCProfileMax;
6623 status = false;
6624 break;
6625 }
6626
6627 if (!status) {
6628 return status;
6629 }
6630
6631 switch (profile_level.level) {
6632 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
6633 *eLevel = OMX_VIDEO_AVCLevel1;
6634 break;
6635 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
6636 *eLevel = OMX_VIDEO_AVCLevel1b;
6637 break;
6638 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
6639 *eLevel = OMX_VIDEO_AVCLevel11;
6640 break;
6641 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
6642 *eLevel = OMX_VIDEO_AVCLevel12;
6643 break;
6644 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
6645 *eLevel = OMX_VIDEO_AVCLevel13;
6646 break;
6647 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
6648 *eLevel = OMX_VIDEO_AVCLevel2;
6649 break;
6650 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
6651 *eLevel = OMX_VIDEO_AVCLevel21;
6652 break;
6653 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
6654 *eLevel = OMX_VIDEO_AVCLevel22;
6655 break;
6656 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
6657 *eLevel = OMX_VIDEO_AVCLevel3;
6658 break;
6659 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
6660 *eLevel = OMX_VIDEO_AVCLevel31;
6661 break;
6662 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
6663 *eLevel = OMX_VIDEO_AVCLevel32;
6664 break;
6665 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
6666 *eLevel = OMX_VIDEO_AVCLevel4;
6667 break;
6668 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
6669 *eLevel = OMX_VIDEO_AVCLevel41;
6670 break;
6671 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
6672 *eLevel = OMX_VIDEO_AVCLevel42;
6673 break;
6674 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
6675 *eLevel = OMX_VIDEO_AVCLevel5;
6676 break;
6677 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
6678 *eLevel = OMX_VIDEO_AVCLevel51;
6679 break;
6680 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
6681 *eLevel = OMX_VIDEO_AVCLevel52;
6682 break;
6683 default :
6684 *eLevel = OMX_VIDEO_AVCLevelMax;
6685 status = false;
6686 break;
6687 }
6688 }
6689 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6690 switch (codec_profile.profile) {
6691 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6692 *eProfile = OMX_VIDEO_VP8ProfileMain;
6693 break;
6694 default:
6695 *eProfile = OMX_VIDEO_VP8ProfileMax;
6696 status = false;
6697 break;
6698 }
6699 if (!status) {
6700 return status;
6701 }
6702
6703 switch (profile_level.level) {
6704 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6705 *eLevel = OMX_VIDEO_VP8Level_Version0;
6706 break;
6707 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6708 *eLevel = OMX_VIDEO_VP8Level_Version1;
6709 break;
6710 default:
6711 *eLevel = OMX_VIDEO_VP8LevelMax;
6712 status = false;
6713 break;
6714 }
6715 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6716 switch (codec_profile.profile) {
6717 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6718 *eProfile = OMX_VIDEO_HEVCProfileMain;
6719 break;
6720 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6721 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6722 break;
6723 default:
6724 *eProfile = OMX_VIDEO_HEVCProfileMax;
6725 status = false;
6726 break;
6727 }
6728 if (!status) {
6729 return status;
6730 }
6731
6732 switch (profile_level.level) {
6733 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
6734 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
6735 break;
6736 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
6737 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
6738 break;
6739 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
6740 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
6741 break;
6742 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
6743 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
6744 break;
6745 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
6746 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
6747 break;
6748 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
6749 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
6750 break;
6751 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
6752 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
6753 break;
6754 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
6755 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
6756 break;
6757 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
6758 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
6759 break;
6760 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
6761 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
6762 break;
6763 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
6764 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
6765 break;
6766 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
6767 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
6768 break;
6769 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
6770 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
6771 break;
6772 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
6773 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
6774 break;
6775 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
6776 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
6777 break;
6778 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
6779 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
6780 break;
6781 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
6782 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
6783 break;
6784 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
6785 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
6786 break;
6787 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
6788 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
6789 break;
6790 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
6791 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
6792 break;
6793 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
6794 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
6795 break;
6796 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
6797 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
6798 break;
6799 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
6800 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
6801 break;
6802 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
6803 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
6804 break;
6805 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
6806 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
6807 break;
6808 default:
6809 *eLevel = OMX_VIDEO_HEVCLevelMax;
6810 status = false;
6811 break;
6812 }
6813 }
6814
6815 return status;
6816 }
6817
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6818 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
6819 {
6820 OMX_U32 new_profile = 0, new_level = 0;
6821 unsigned const int *profile_tbl = NULL;
6822 OMX_U32 mb_per_frame, mb_per_sec;
6823 bool profile_level_found = false;
6824
6825 DEBUG_PRINT_LOW("Init profile table for respective codec");
6826
6827 //validate the ht,width,fps,bitrate and set the appropriate profile and level
6828 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6829 if (*eProfile == 0) {
6830 if (!m_profile_set) {
6831 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6832 } else {
6833 switch (codec_profile.profile) {
6834 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6835 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6836 break;
6837 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6838 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6839 break;
6840 default:
6841 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6842 return false;
6843 }
6844 }
6845 }
6846
6847 if (*eLevel == 0 && !m_level_set) {
6848 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6849 }
6850
6851 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
6852 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
6853 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
6854 profile_tbl = (unsigned int const *)
6855 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
6856 } else {
6857 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
6858 return false;
6859 }
6860 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6861 if (*eProfile == 0) {
6862 if (!m_profile_set) {
6863 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6864 } else {
6865 switch (codec_profile.profile) {
6866 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6867 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6868 break;
6869 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6870 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6871 break;
6872 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6873 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6874 break;
6875 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6876 *eProfile = OMX_VIDEO_AVCProfileMain;
6877 break;
6878 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6879 *eProfile = OMX_VIDEO_AVCProfileExtended;
6880 break;
6881 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6882 *eProfile = OMX_VIDEO_AVCProfileHigh;
6883 break;
6884 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6885 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6886 break;
6887 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6888 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6889 break;
6890 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6891 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6892 break;
6893 default:
6894 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6895 return false;
6896 }
6897 }
6898 }
6899
6900 if (*eLevel == 0 && !m_level_set) {
6901 *eLevel = OMX_VIDEO_AVCLevelMax;
6902 }
6903
6904 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
6905 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
6906 profile_tbl = (unsigned int const *)h264_profile_level_table;
6907 } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
6908 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
6909 profile_tbl = (unsigned int const *)
6910 (&h264_profile_level_table[H264_HP_START]);
6911 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
6912 profile_tbl = (unsigned int const *)
6913 (&h264_profile_level_table[H264_MP_START]);
6914 } else {
6915 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
6916 return false;
6917 }
6918 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6919 if (*eProfile == 0) {
6920 if (!m_profile_set) {
6921 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6922 } else {
6923 switch (codec_profile.profile) {
6924 case VEN_PROFILE_H263_BASELINE:
6925 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6926 break;
6927 default:
6928 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6929 return false;
6930 }
6931 }
6932 }
6933
6934 if (*eLevel == 0 && !m_level_set) {
6935 *eLevel = OMX_VIDEO_H263LevelMax;
6936 }
6937
6938 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
6939 profile_tbl = (unsigned int const *)h263_profile_level_table;
6940 } else {
6941 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
6942 return false;
6943 }
6944 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6945 if (*eProfile == 0) {
6946 *eProfile = OMX_VIDEO_VP8ProfileMain;
6947 } else {
6948 switch (codec_profile.profile) {
6949 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6950 *eProfile = OMX_VIDEO_VP8ProfileMain;
6951 break;
6952 default:
6953 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
6954 return false;
6955 }
6956 }
6957 if (*eLevel == 0) {
6958 switch (profile_level.level) {
6959 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6960 *eLevel = OMX_VIDEO_VP8Level_Version0;
6961 break;
6962 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6963 *eLevel = OMX_VIDEO_VP8Level_Version1;
6964 break;
6965 default:
6966 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
6967 return false;
6968 }
6969 }
6970 return true;
6971 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6972 if (*eProfile == 0) {
6973 if (!m_profile_set) {
6974 *eProfile = OMX_VIDEO_HEVCProfileMain;
6975 } else {
6976 switch (codec_profile.profile) {
6977 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6978 *eProfile = OMX_VIDEO_HEVCProfileMain;
6979 break;
6980 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6981 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6982 break;
6983 default:
6984 DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
6985 return false;
6986 }
6987 }
6988 }
6989
6990 if (*eLevel == 0 && !m_level_set) {
6991 *eLevel = OMX_VIDEO_HEVCLevelMax;
6992 }
6993
6994 if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
6995 profile_tbl = (unsigned int const *)hevc_profile_level_table;
6996 } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
6997 profile_tbl = (unsigned int const *)
6998 (&hevc_profile_level_table[HEVC_MAIN10_START]);
6999 } else {
7000 DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
7001 return false;
7002 }
7003 } else {
7004 DEBUG_PRINT_ERROR("Invalid codec type");
7005 return false;
7006 }
7007
7008 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
7009 ((m_sVenc_cfg.dvs_width + 15)>> 4);
7010
7011 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
7012 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
7013 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7014
7015 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
7016 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7017
7018 {
7019 new_level = profile_level.level;
7020 new_profile = codec_profile.profile;
7021 return true;
7022 }
7023 }
7024
7025 if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
7026 *eLevel = rc_off_level; //No level calculation for RC_OFF
7027 profile_level_found = true;
7028 return true;
7029 }
7030
7031 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
7032
7033 bool h264, ltr, hlayers;
7034 unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
7035 h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
7036 ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7037 hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
7038 ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
7039
7040 /* Hybrid HP reference buffers:
7041 layers = 1, 2 need 1 reference buffer
7042 layers = 3, 4 need 2 reference buffers
7043 layers = 5, 6 need 3 reference buffers
7044 */
7045
7046 if(hier_layers.hier_mode == HIER_P_HYBRID)
7047 hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
7048
7049 do {
7050 if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
7051 if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
7052 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
7053 if (h264 && (ltr || hlayers || hybridp)) {
7054 // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
7055 new_level = (int)profile_tbl[3];
7056 new_profile = (int)profile_tbl[4];
7057 profile_level_found = true;
7058 DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
7059 ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
7060 MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7061 break;
7062 } else {
7063 new_level = (int)profile_tbl[3];
7064 new_profile = (int)profile_tbl[4];
7065 profile_level_found = true;
7066 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
7067 break;
7068 }
7069 }
7070 }
7071 }
7072 profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
7073 } while (profile_tbl[0] != 0);
7074
7075 if (profile_level_found != true) {
7076 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
7077 return false;
7078 }
7079
7080 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
7081 || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
7082 || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
7083 *eLevel = new_level;
7084 }
7085
7086 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
7087 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
7088
7089 return true;
7090 }
7091 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)7092 bool venc_dev::venc_set_meta_mode(bool mode)
7093 {
7094 metadatamode = mode;
7095 return true;
7096 }
7097 #endif
7098
venc_is_video_session_supported(unsigned long width,unsigned long height)7099 bool venc_dev::venc_is_video_session_supported(unsigned long width,
7100 unsigned long height)
7101 {
7102 if ((width * height < capability.min_width * capability.min_height) ||
7103 (width * height > capability.max_width * capability.max_height)) {
7104 DEBUG_PRINT_ERROR(
7105 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
7106 width, height, capability.min_width, capability.min_height,
7107 capability.max_width, capability.max_height);
7108 return false;
7109 }
7110
7111 DEBUG_PRINT_LOW("video session supported");
7112 return true;
7113 }
7114
venc_set_batch_size(OMX_U32 batchSize)7115 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
7116 {
7117 struct v4l2_control control;
7118 int ret;
7119
7120 control.id = V4L2_CID_VIDC_QBUF_MODE;
7121 control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
7122
7123 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
7124 if (ret) {
7125 DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
7126 return false;
7127 }
7128
7129 mBatchSize = batchSize;
7130 DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
7131 return true;
7132 }
7133
BatchInfo()7134 venc_dev::BatchInfo::BatchInfo()
7135 : mNumPending(0) {
7136 pthread_mutex_init(&mLock, NULL);
7137 for (int i = 0; i < kMaxBufs; ++i) {
7138 mBufMap[i] = kBufIDFree;
7139 }
7140 }
7141
registerBuffer(int bufferId)7142 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
7143 pthread_mutex_lock(&mLock);
7144 int availId = 0;
7145 for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
7146 if (availId >= kMaxBufs) {
7147 DEBUG_PRINT_ERROR("Failed to find free entry !");
7148 pthread_mutex_unlock(&mLock);
7149 return -1;
7150 }
7151 mBufMap[availId] = bufferId;
7152 mNumPending++;
7153 pthread_mutex_unlock(&mLock);
7154 return availId;
7155 }
7156
retrieveBufferAt(int v4l2Id)7157 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
7158 pthread_mutex_lock(&mLock);
7159 if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
7160 DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
7161 pthread_mutex_unlock(&mLock);
7162 return -1;
7163 }
7164 if (mBufMap[v4l2Id] == kBufIDFree) {
7165 DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
7166 pthread_mutex_unlock(&mLock);
7167 return -1;
7168 }
7169 int bufferId = mBufMap[v4l2Id];
7170 mBufMap[v4l2Id] = kBufIDFree;
7171 mNumPending--;
7172 pthread_mutex_unlock(&mLock);
7173 return bufferId;
7174 }
7175
isPending(int bufferId)7176 bool venc_dev::BatchInfo::isPending(int bufferId) {
7177 pthread_mutex_lock(&mLock);
7178 int existsId = 0;
7179 for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
7180 pthread_mutex_unlock(&mLock);
7181 return existsId < kMaxBufs;
7182 }
7183
getFdAt(native_handle_t * hnd,int index)7184 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
7185 int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
7186 return fd;
7187 }
7188
getOffsetAt(native_handle_t * hnd,int index)7189 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
7190 int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
7191 return off;
7192 }
7193
getSizeAt(native_handle_t * hnd,int index)7194 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
7195 int size = hnd && (index + hnd->numFds) < hnd->numInts ?
7196 hnd->data[2*hnd->numFds + index] : -1;
7197 return size;
7198 }
7199
getColorFormatAt(native_handle_t * hnd,int index)7200 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
7201 int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
7202 hnd->data[3*hnd->numFds + index] : 0;
7203 return usage;
7204 }
7205
getTimeStampAt(native_handle_t * hnd,int index)7206 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
7207 int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
7208 hnd->data[4*hnd->numFds + index] : -1;
7209 return size;
7210 }
7211
7212 #ifdef _VQZIP_
venc_dev_vqzip()7213 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
7214 {
7215 mLibHandle = NULL;
7216 pthread_mutex_init(&lock, NULL);
7217 }
7218
init()7219 bool venc_dev::venc_dev_vqzip::init()
7220 {
7221 bool status = true;
7222 if (mLibHandle) {
7223 DEBUG_PRINT_ERROR("VQZIP init called twice");
7224 status = false;
7225 }
7226 if (status) {
7227 mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
7228 if (mLibHandle) {
7229 mVQZIPInit = (vqzip_init_t)
7230 dlsym(mLibHandle,"VQZipInit");
7231 mVQZIPDeInit = (vqzip_deinit_t)
7232 dlsym(mLibHandle,"VQZipDeInit");
7233 mVQZIPComputeStats = (vqzip_compute_stats_t)
7234 dlsym(mLibHandle,"VQZipComputeStats");
7235 if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
7236 status = false;
7237 } else {
7238 DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
7239 status = false;
7240 }
7241 if (status) {
7242 mVQZIPHandle = mVQZIPInit();
7243 }
7244 }
7245 if (!status && mLibHandle) {
7246 dlclose(mLibHandle);
7247 mLibHandle = NULL;
7248 mVQZIPHandle = NULL;
7249 mVQZIPInit = NULL;
7250 mVQZIPDeInit = NULL;
7251 mVQZIPComputeStats = NULL;
7252 }
7253 return status;
7254 }
7255
fill_stats_data(void * pBuf,void * extraData)7256 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
7257 {
7258 VQZipStatus result;
7259 VQZipStats *pStats = (VQZipStats *)extraData;
7260 pConfig.pSEIPayload = NULL;
7261 unsigned long size;
7262
7263 if (!pBuf || !pStats || !mVQZIPHandle) {
7264 DEBUG_PRINT_ERROR("Invalid data passed to stats function");
7265 }
7266 result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
7267 return (result < 0);
7268 }
7269
deinit()7270 void venc_dev::venc_dev_vqzip::deinit()
7271 {
7272 if (mLibHandle) {
7273 pthread_mutex_lock(&lock);
7274 dlclose(mLibHandle);
7275 mVQZIPDeInit(mVQZIPHandle);
7276 mLibHandle = NULL;
7277 mVQZIPHandle = NULL;
7278 mVQZIPInit = NULL;
7279 mVQZIPDeInit = NULL;
7280 mVQZIPComputeStats = NULL;
7281 pthread_mutex_unlock(&lock);
7282 }
7283 }
7284
~venc_dev_vqzip()7285 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
7286 {
7287 DEBUG_PRINT_HIGH("Destroy C2D instance");
7288 if (mLibHandle) {
7289 dlclose(mLibHandle);
7290 }
7291 mLibHandle = NULL;
7292 pthread_mutex_destroy(&lock);
7293 }
7294 #endif
7295
encExtradata(class omx_venc * venc_handle)7296 encExtradata::encExtradata(class omx_venc *venc_handle)
7297 {
7298 mCount = 0;
7299 mSize = 0;
7300 mUaddr = NULL;
7301 memset(&mIon, -1, sizeof(struct venc_ion));
7302 memset(mIndex, 0, sizeof(mIndex));
7303 mVencHandle = venc_handle;
7304 mDbgEtbCount = 0;
7305 pthread_mutex_init(&lock, NULL);
7306 vqzip_sei_found = false;
7307 }
7308
~encExtradata()7309 encExtradata::~encExtradata()
7310 {
7311 __free();
7312 mCount = 0;
7313 mSize = 0;
7314 mVencHandle = NULL;
7315 pthread_mutex_destroy(&lock);
7316 }
7317
__allocate()7318 OMX_ERRORTYPE encExtradata::__allocate()
7319 {
7320 ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
7321 if (!mVencHandle) {
7322 return OMX_ErrorInsufficientResources;
7323 }
7324 if (mUaddr || !totalSize) {
7325 return OMX_ErrorNone;
7326 }
7327 mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
7328 totalSize,
7329 &mIon.ion_alloc_data,
7330 &mIon.fd_ion_data, 0);
7331 if (mIon.ion_device_fd < 0) {
7332 DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
7333 DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
7334 return OMX_ErrorInsufficientResources;
7335 }
7336 mUaddr = (char *)mmap(NULL, totalSize,
7337 PROT_READ|PROT_WRITE, MAP_SHARED,
7338 mIon.fd_ion_data.fd , 0);
7339 if (mUaddr == MAP_FAILED) {
7340 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
7341 close(mIon.fd_ion_data.fd);
7342 mVencHandle->free_ion_memory(&mIon);
7343 return OMX_ErrorInsufficientResources;
7344 }
7345 for (unsigned i = 0; i < mCount; i++) {
7346 mIndex[i].status = FREE;
7347 mIndex[i].cookie = NULL;
7348 }
7349 return OMX_ErrorNone;
7350 }
7351
__get(char ** userptr,int * fd,unsigned * offset,ssize_t * size,int type)7352 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
7353 {
7354 unsigned i = 0;
7355 if (__allocate() != OMX_ErrorNone) {
7356 return -1;
7357 }
7358 for (i = 0; i < mCount; i++) {
7359 if (mIndex[i].status == type) {
7360 mIndex[i].status = BUSY;
7361 break;
7362 }
7363 }
7364 if (i >= mCount) {
7365 DEBUG_PRINT_HIGH("No Free extradata available");
7366 return -1;
7367 }
7368 *userptr = mUaddr + i * mSize;
7369 *fd = mIon.fd_ion_data.fd;
7370 *offset = i * mSize;
7371 *size = mSize;
7372 return i;
7373 }
7374
get(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7375 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
7376 int index;
7377 *userptr = NULL;
7378 *fd = -1;
7379 *offset = 0;
7380 *size = 0;
7381 pthread_mutex_lock(&lock);
7382 index = __get(userptr, fd, offset, size, FREE);
7383 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7384 pthread_mutex_unlock(&lock);
7385 return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
7386 }
7387
get(void * cookie,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7388 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
7389 {
7390 OMX_ERRORTYPE rc = OMX_ErrorNone;
7391 unsigned int i;
7392 *userptr = NULL;
7393 *fd = -1;
7394 *offset = 0;
7395 *size = 0;
7396 pthread_mutex_lock(&lock);
7397 for (i = 0; i < mCount; i++) {
7398 if (mIndex[i].cookie == cookie) {
7399 break;
7400 }
7401 }
7402 if (i < mCount) {
7403 *userptr = mUaddr + i * mSize;
7404 *fd = mIon.fd_ion_data.fd;
7405 *offset = i * mSize;
7406 *size = mSize;
7407 } else {
7408 int index = __get(userptr, fd, offset, size, FREE);
7409 if (index < 0 ) {
7410 DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
7411 __debug();
7412 rc = OMX_ErrorInsufficientResources;
7413 }
7414 }
7415 DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
7416 pthread_mutex_unlock(&lock);
7417 return rc;
7418 }
7419
getForConfig(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7420 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
7421 {
7422 OMX_ERRORTYPE rc = OMX_ErrorNone;
7423 unsigned int i;
7424 int found = -1;
7425 pthread_mutex_lock(&lock);
7426 found = __get(userptr, fd, offset, size, FOR_CONFIG);
7427 if (found < 0) {
7428 found = __get(userptr, fd, offset, size, FREE);
7429 }
7430
7431 if (found < 0) {
7432 DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
7433 __debug();
7434 rc = OMX_ErrorInsufficientResources;
7435 } else {
7436 mIndex[found].status = FOR_CONFIG;
7437 DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
7438 }
7439 pthread_mutex_unlock(&lock);
7440 return rc;
7441 }
7442
put(char * userptr)7443 OMX_ERRORTYPE encExtradata::put(char *userptr)
7444 {
7445 OMX_ERRORTYPE rc = OMX_ErrorNone;
7446 int index = (userptr - mUaddr)/mSize;
7447 pthread_mutex_lock(&lock);
7448 if (!userptr) {
7449 DEBUG_PRINT_HIGH("Userptr is NULL");
7450 rc = OMX_ErrorBadParameter;
7451 } else if (index < 0) {
7452 DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
7453 __debug();
7454 rc = OMX_ErrorBadParameter;
7455 } else {
7456 mIndex[index].status = FREE;
7457 mIndex[index].cookie = NULL;
7458 DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
7459 }
7460 pthread_mutex_unlock(&lock);
7461 return rc;
7462 }
7463
peek(unsigned index,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7464 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
7465 {
7466 OMX_ERRORTYPE rc = OMX_ErrorNone;
7467 *userptr = 0;
7468 *fd = -1;
7469 *offset = 0;
7470 *size = 0;
7471 pthread_mutex_lock(&lock);
7472 if (index < mCount) {
7473 rc = __allocate();
7474 if (rc == OMX_ErrorNone) {
7475 *userptr = mUaddr + index * mSize;
7476 *fd = mIon.fd_ion_data.fd;
7477 *offset = index * mSize;
7478 *size = mSize;
7479 }
7480 }
7481 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7482 pthread_mutex_unlock(&lock);
7483 return rc;
7484 }
7485
setCookieForConfig(void * cookie)7486 void encExtradata::setCookieForConfig(void *cookie)
7487 {
7488 char *userptr;
7489 int fd;
7490 unsigned offset;
7491 ssize_t size;
7492 pthread_mutex_lock(&lock);
7493 int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
7494 if (found >= 0) {
7495 mIndex[found].cookie = cookie;
7496 } else {
7497 DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
7498 found, cookie);
7499 __debug();
7500 }
7501 mDbgEtbCount++;
7502 pthread_mutex_unlock(&lock);
7503 }
7504
__free()7505 void encExtradata::__free()
7506 {
7507 ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
7508 if (mUaddr) {
7509 munmap((void *)mUaddr, totalSize);
7510 mUaddr = NULL;
7511 }
7512 if (mIon.fd_ion_data.fd >= 0) {
7513 if (mVencHandle)
7514 mVencHandle->free_ion_memory(&mIon);
7515 close(mIon.fd_ion_data.fd);
7516 mIon.fd_ion_data.fd = -1;
7517 }
7518 for (unsigned i = 0; i < mCount; i++) {
7519 mIndex[i].status = FREE;
7520 mIndex[i].cookie = NULL;
7521 }
7522 }
7523
update(unsigned int count,ssize_t size)7524 void encExtradata::update(unsigned int count, ssize_t size)
7525 {
7526 pthread_mutex_lock(&lock);
7527 __free();
7528 mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
7529 mSize = size;
7530 DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
7531 pthread_mutex_unlock(&lock);
7532 }
7533
__debug()7534 void encExtradata::__debug()
7535 {
7536 DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
7537 this, mCount, mSize, mUaddr, mVencHandle);
7538 for (unsigned i = 0; i < mCount; i++) {
7539 DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
7540 }
7541 }
7542
getBufferSize()7543 ssize_t encExtradata::getBufferSize()
7544 {
7545 return mSize;
7546 }
7547
getBufferCount()7548 unsigned int encExtradata::getBufferCount()
7549 {
7550 return mCount;
7551 }
7552