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) OMX_VIDEO_AVCProfileConstrainedBaseline) &&
1863 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1864 if (pParam->nBFrames) {
1865 bFrames = pParam->nBFrames;
1866 }
1867 } else {
1868 if (pParam->nBFrames) {
1869 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1870 bFrames = 0;
1871 }
1872 }
1873 }
1874
1875 if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) {
1876 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1877 return false;
1878 }
1879
1880 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1881 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1882 return false;
1883 }
1884
1885 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1886 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1887 return false;
1888 }
1889
1890 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1891 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1892 return false;
1893 }
1894 } else {
1895 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1896 }
1897
1898 //TBD, lot of other variables to be updated, yet to decide
1899 break;
1900 }
1901 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1902 {
1903 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1904 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1905 rc_off_level = (int)pParam->eLevel;
1906 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1907 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1908 pParam->eProfile, pParam->eLevel);
1909 return false;
1910 }
1911 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1912 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1913 return false;
1914 }
1915 if(!venc_set_ltrmode(1, 1)) {
1916 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1917 return false;
1918 }
1919
1920 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1921 // Disable hier-p if ltr is enabled.
1922 if (m_codec == OMX_VIDEO_CodingVP8) {
1923 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1924 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1925 DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1926 }
1927 }
1928
1929 break;
1930 }
1931 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1932 {
1933 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1934 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1935 rc_off_level = (int)pParam->eLevel;
1936 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1937 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1938 pParam->eProfile, pParam->eLevel);
1939 return false;
1940 }
1941 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1942 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1943
1944 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1945 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1946 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1947 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1948 return false;
1949 }
1950 break;
1951 }
1952 case OMX_IndexParamVideoIntraRefresh:
1953 {
1954 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1955 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1956 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1957
1958 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1959 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1960 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1961 return false;
1962 }
1963 } else {
1964 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1965 }
1966
1967 break;
1968 }
1969 case OMX_IndexParamVideoErrorCorrection:
1970 {
1971 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1972 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1973 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1974
1975 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1976 if (venc_set_error_resilience(error_resilience) == false) {
1977 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1978 return false;
1979 }
1980 } else {
1981 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1982 }
1983
1984 break;
1985 }
1986 case OMX_IndexParamVideoProfileLevelCurrent:
1987 {
1988 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1989 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1990 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1991
1992 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1993 m_profile_set = false;
1994 m_level_set = false;
1995 rc_off_level = (int)profile_level->eLevel;
1996 if (!venc_set_profile_level (profile_level->eProfile,
1997 profile_level->eLevel)) {
1998 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1999 return false;
2000 }
2001 } else {
2002 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
2003 }
2004
2005 break;
2006 }
2007 case OMX_IndexParamVideoQuantization:
2008 {
2009 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
2010 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
2011 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
2012 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2013 if (venc_set_session_qp (session_qp->nQpI,
2014 session_qp->nQpP,
2015 session_qp->nQpB) == false) {
2016 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
2017 return false;
2018 }
2019 } else {
2020 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
2021 }
2022
2023 break;
2024 }
2025 case QOMX_IndexParamVideoInitialQp:
2026 {
2027 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
2028 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
2029 if (initqp->bEnableInitQp) {
2030 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
2031 if(venc_enable_initial_qp(initqp) == false) {
2032 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
2033 return OMX_ErrorUnsupportedSetting;
2034 }
2035 } else
2036 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
2037 break;
2038 }
2039 case OMX_QcomIndexParamVideoQPRange:
2040 {
2041 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
2042 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
2043 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
2044
2045 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2046 if(venc_set_session_qp_range (session_qp_range->minQP,
2047 session_qp_range->maxQP) == false) {
2048 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
2049 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
2050 return false;
2051 } else {
2052 session_qp_values.minqp = session_qp_range->minQP;
2053 session_qp_values.maxqp = session_qp_range->maxQP;
2054 }
2055 } else {
2056 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
2057 }
2058
2059 break;
2060 }
2061 case OMX_QcomIndexEnableSliceDeliveryMode:
2062 {
2063 QOMX_EXTNINDEX_PARAMTYPE* pParam =
2064 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
2065
2066 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2067 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
2068 DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
2069 return OMX_ErrorUnsupportedSetting;
2070 }
2071 } else {
2072 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
2073 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
2074 return OMX_ErrorBadPortIndex;
2075 }
2076
2077 break;
2078 }
2079 case OMX_ExtraDataFrameDimension:
2080 {
2081 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
2082 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2083
2084 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
2085 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
2086 return false;
2087 }
2088
2089 extradata = true;
2090 break;
2091 }
2092 case OMX_ExtraDataVideoEncoderSliceInfo:
2093 {
2094 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
2095 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2096
2097 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
2098 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
2099 return false;
2100 }
2101
2102 extradata = true;
2103 break;
2104 }
2105 case OMX_ExtraDataVideoEncoderMBInfo:
2106 {
2107 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
2108 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
2109
2110 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
2111 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
2112 return false;
2113 }
2114
2115 extradata = true;
2116 break;
2117 }
2118 case OMX_QcomIndexParamSequenceHeaderWithIDR:
2119 {
2120 PrependSPSPPSToIDRFramesParams * pParam =
2121 (PrependSPSPPSToIDRFramesParams *)paramData;
2122
2123 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
2124 if(venc_set_inband_video_header(pParam->bEnable) == false) {
2125 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
2126 return OMX_ErrorUnsupportedSetting;
2127 }
2128
2129 break;
2130 }
2131 case OMX_QcomIndexParamH264AUDelimiter:
2132 {
2133 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
2134 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
2135
2136 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
2137 if(venc_set_au_delimiter(pParam->bEnable) == false) {
2138 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
2139 return OMX_ErrorUnsupportedSetting;
2140 }
2141
2142 break;
2143 }
2144 case OMX_QcomIndexParamMBIStatisticsMode:
2145 {
2146 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
2147 (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
2148
2149 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
2150 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
2151 DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
2152 return OMX_ErrorUnsupportedSetting;
2153 }
2154
2155 break;
2156 }
2157
2158 case OMX_QcomIndexConfigH264EntropyCodingCabac:
2159 {
2160 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
2161 (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
2162
2163 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
2164 if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
2165 DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
2166 return OMX_ErrorUnsupportedSetting;
2167 }
2168
2169 break;
2170 }
2171
2172 case OMX_QcomIndexHierarchicalStructure:
2173 {
2174 QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
2175 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
2176
2177 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2178 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
2179 DEBUG_PRINT_ERROR("Setting Hier P count failed");
2180 return false;
2181 }
2182 } else {
2183 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
2184 return false;
2185 }
2186
2187 // For VP8, hier-p and ltr are mutually exclusive features in firmware
2188 // Disable ltr if hier-p is enabled.
2189 if (m_codec == OMX_VIDEO_CodingVP8) {
2190 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
2191 if(!venc_set_ltrmode(0, 1)) {
2192 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
2193 }
2194 }
2195 break;
2196 }
2197 case OMX_QcomIndexParamPerfLevel:
2198 {
2199 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
2200 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
2201 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
2202 if (!venc_set_perf_level(pParam->ePerfLevel)) {
2203 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
2204 return false;
2205 } else {
2206 performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
2207 }
2208 break;
2209 }
2210 case OMX_QcomIndexParamH264VUITimingInfo:
2211 {
2212 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
2213 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
2214 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
2215 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
2216 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
2217 return false;
2218 } else {
2219 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
2220 }
2221 break;
2222 }
2223 case OMX_QTIIndexParamVQZIPSEIType:
2224 {
2225 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
2226 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
2227 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
2228 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
2229 DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
2230 return false;
2231 }
2232 break;
2233 }
2234 case OMX_QcomIndexParamPeakBitrate:
2235 {
2236 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
2237 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
2238 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
2239 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
2240 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
2241 return false;
2242 } else {
2243 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
2244 }
2245 break;
2246 }
2247 case OMX_QcomIndexParamSetMVSearchrange:
2248 {
2249 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
2250 is_searchrange_set = true;
2251 if (!venc_set_searchrange()) {
2252 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
2253 return false;
2254 }
2255 }
2256 break;
2257 case OMX_QcomIndexParamVideoLTRCount:
2258 {
2259 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
2260 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
2261 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
2262 if (pParam->nCount > 0) {
2263 if (venc_set_ltrmode(1, pParam->nCount) == false) {
2264 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
2265 return false;
2266 }
2267 } else {
2268 if (venc_set_ltrmode(0, 0) == false) {
2269 DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
2270 return false;
2271 }
2272 }
2273 break;
2274 }
2275 case OMX_QcomIndexParamVideoHybridHierpMode:
2276 {
2277 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
2278 DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
2279 return false;
2280 }
2281 break;
2282 }
2283 case OMX_QcomIndexParamBatchSize:
2284 {
2285 OMX_PARAM_U32TYPE* pParam =
2286 (OMX_PARAM_U32TYPE*)paramData;
2287
2288 if (pParam->nPortIndex == PORT_INDEX_OUT) {
2289 DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
2290 " on output port");
2291 return OMX_ErrorUnsupportedSetting;
2292 }
2293
2294 if (!venc_set_batch_size(pParam->nU32)) {
2295 DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
2296 return OMX_ErrorUnsupportedSetting;
2297 }
2298 break;
2299 }
2300 case OMX_QcomIndexParamVencAspectRatio:
2301 {
2302 if (!venc_set_aspectratio(paramData)) {
2303 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
2304 return OMX_ErrorUnsupportedSetting;
2305 }
2306 break;
2307 }
2308 case OMX_QTIIndexParamVideoEnableRoiInfo:
2309 {
2310 struct v4l2_control control;
2311 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
2312 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
2313 DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
2314 return OMX_ErrorUnsupportedSetting;
2315 }
2316 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2317 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
2318 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
2319 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2320 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
2321 return OMX_ErrorUnsupportedSetting;
2322 }
2323 break;
2324 }
2325 case OMX_IndexParamAndroidVideoTemporalLayering:
2326 {
2327 if (venc_set_temporal_layers(
2328 (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
2329 DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
2330 return false;
2331 }
2332 break;
2333 }
2334 case OMX_QTIIndexParamEnableAVTimerTimestamps:
2335 {
2336 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
2337 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
2338 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
2339 break;
2340 }
2341 case OMX_IndexParamVideoSliceFMO:
2342 default:
2343 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
2344 index);
2345 break;
2346 //case
2347 }
2348
2349 return true;
2350 }
2351
venc_check_valid_config()2352 bool venc_dev::venc_check_valid_config()
2353 {
2354 if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
2355 ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
2356 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
2357 DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
2358 DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
2359 DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
2360 return false;
2361 }
2362 return true;
2363 }
2364
venc_set_config(void * configData,OMX_INDEXTYPE index)2365 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
2366 {
2367
2368 DEBUG_PRINT_LOW("Inside venc_set_config");
2369
2370 if(!venc_check_valid_config()) {
2371 DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
2372 return false;
2373 }
2374
2375 switch ((int)index) {
2376 case OMX_IndexConfigVideoBitrate:
2377 {
2378 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
2379 configData;
2380 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
2381
2382 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2383 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
2384 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
2385 return false;
2386 }
2387 } else {
2388 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
2389 }
2390
2391 break;
2392 }
2393 case OMX_IndexConfigVideoFramerate:
2394 {
2395 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
2396 configData;
2397 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
2398
2399 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2400 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
2401 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2402 return false;
2403 }
2404 } else {
2405 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2406 }
2407
2408 break;
2409 }
2410 case QOMX_IndexConfigVideoIntraperiod:
2411 {
2412 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
2413 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
2414 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
2415
2416 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2417 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
2418 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
2419 return false;
2420 }
2421 }
2422
2423 break;
2424 }
2425 case OMX_IndexConfigVideoIntraVOPRefresh:
2426 {
2427 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
2428 configData;
2429 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
2430
2431 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2432 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2433 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2434 return false;
2435 }
2436 } else {
2437 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2438 }
2439
2440 break;
2441 }
2442 case OMX_IndexConfigCommonRotate:
2443 {
2444 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2445 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2446 OMX_U32 nFrameWidth;
2447 if (!config_rotation) {
2448 return false;
2449 }
2450 if (true == deinterlace_enabled) {
2451 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2452 return false;
2453 }
2454 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2455 nFrameWidth = m_sVenc_cfg.dvs_width;
2456 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height;
2457 m_sVenc_cfg.dvs_height = nFrameWidth;
2458
2459 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2460 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2461 return false;
2462 }
2463
2464 break;
2465 }
2466 case OMX_IndexConfigVideoAVCIntraPeriod:
2467 {
2468 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2469 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2470
2471 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2472 == false) {
2473 DEBUG_PRINT_ERROR("ERROR: Setting "
2474 "OMX_IndexConfigVideoAVCIntraPeriod failed");
2475 return false;
2476 }
2477 break;
2478 }
2479 case OMX_IndexConfigCommonDeinterlace:
2480 {
2481 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2482 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2483 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2484 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2485 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2486 {
2487 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2488 return false;
2489 }
2490 if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2491 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2492 return false;
2493 }
2494 } else {
2495 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2496 }
2497 break;
2498 }
2499 case OMX_IndexConfigVideoVp8ReferenceFrame:
2500 {
2501 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2502 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2503 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2504 (vp8refframe->bUseGoldenFrame)) {
2505 if(venc_set_useltr(0x1) == false) {
2506 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2507 return false;
2508 }
2509 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2510 (vp8refframe->bGoldenFrameRefresh)) {
2511 if(venc_set_markltr(0x1) == false) {
2512 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2513 return false;
2514 }
2515 } else {
2516 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2517 }
2518 break;
2519 }
2520 case OMX_QcomIndexConfigVideoLTRUse:
2521 {
2522 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2523 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2524 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2525 if (venc_set_useltr(pParam->nID) == false) {
2526 DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2527 return false;
2528 }
2529 } else {
2530 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2531 }
2532 break;
2533 }
2534 case OMX_QcomIndexConfigVideoLTRMark:
2535 {
2536 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2537 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2538 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2539 if (venc_set_markltr(pParam->nID) == false) {
2540 DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2541 return false;
2542 }
2543 } else {
2544 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2545 }
2546 break;
2547 }
2548 case OMX_QcomIndexConfigPerfLevel:
2549 {
2550 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2551 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2552 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2553 if (!venc_set_perf_level(perf->ePerfLevel)) {
2554 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2555 return false;
2556 } else {
2557 performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2558 }
2559 break;
2560 }
2561 case OMX_QcomIndexConfigVideoVencPerfMode:
2562 {
2563 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2564 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2565 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2566 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2567 return false;
2568 }
2569 break;
2570 }
2571 case OMX_QcomIndexConfigNumHierPLayers:
2572 {
2573 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
2574 (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
2575 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
2576 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
2577 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
2578 return false;
2579 }
2580 break;
2581 }
2582 case OMX_QcomIndexConfigBaseLayerId:
2583 {
2584 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
2585 (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
2586 if (venc_set_baselayerid(pParam->nPID) == false) {
2587 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
2588 return OMX_ErrorUnsupportedSetting;
2589 }
2590 break;
2591 }
2592 case OMX_IndexParamAndroidVideoTemporalLayering:
2593 {
2594 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2595 return false;
2596 }
2597 case OMX_QcomIndexConfigQp:
2598 {
2599 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
2600 (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
2601 if (venc_set_qp(pParam->nQP) == false) {
2602 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
2603 return OMX_ErrorUnsupportedSetting;
2604 }
2605 break;
2606 }
2607 case OMX_IndexConfigPriority:
2608 {
2609 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2610 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
2611 if (!venc_set_priority(priority->nU32)) {
2612 DEBUG_PRINT_ERROR("Failed to set priority");
2613 return false;
2614 }
2615 sess_priority.priority = priority->nU32;
2616 break;
2617 }
2618 case OMX_IndexConfigOperatingRate:
2619 {
2620 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2621 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2622 if (!venc_set_operatingrate(rate->nU32)) {
2623 DEBUG_PRINT_ERROR("Failed to set operating rate");
2624 return false;
2625 }
2626 break;
2627 }
2628 case OMX_QTIIndexConfigVideoRoiInfo:
2629 {
2630 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
2631 DEBUG_PRINT_ERROR("Failed to set ROI QP info");
2632 return false;
2633 }
2634 break;
2635 }
2636 case OMX_IndexConfigAndroidIntraRefresh:
2637 {
2638 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2639 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2640
2641 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2642 OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2643 OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2644
2645 if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2646 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2647 return false;
2648 }
2649 } else {
2650 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2651 }
2652 break;
2653 }
2654 case OMX_QTIIndexConfigDescribeColorAspects:
2655 {
2656 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
2657
2658 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
2659 OMX_U32 full_range = 0;
2660 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2661 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2662
2663 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
2664 case ColorAspects::PrimariesBT709_5:
2665 color_space = MSM_VIDC_BT709_5;
2666 break;
2667 case ColorAspects::PrimariesBT470_6M:
2668 color_space = MSM_VIDC_BT470_6_M;
2669 break;
2670 case ColorAspects::PrimariesBT601_6_625:
2671 color_space = MSM_VIDC_BT601_6_625;
2672 break;
2673 case ColorAspects::PrimariesBT601_6_525:
2674 color_space = MSM_VIDC_BT601_6_525;
2675 break;
2676 case ColorAspects::PrimariesGenericFilm:
2677 color_space = MSM_VIDC_GENERIC_FILM;
2678 break;
2679 case ColorAspects::PrimariesBT2020:
2680 color_space = MSM_VIDC_BT2020;
2681 break;
2682 default:
2683 color_space = MSM_VIDC_BT601_6_625;
2684 //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2685 break;
2686 }
2687 switch((ColorAspects::Range)params->sAspects.mRange) {
2688 case ColorAspects::RangeFull:
2689 full_range = 1;
2690 break;
2691 case ColorAspects::RangeLimited:
2692 full_range = 0;
2693 break;
2694 default:
2695 break;
2696 }
2697 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
2698 case ColorAspects::TransferSMPTE170M:
2699 transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
2700 break;
2701 case ColorAspects::TransferUnspecified:
2702 transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
2703 break;
2704 case ColorAspects::TransferGamma22:
2705 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
2706 break;
2707 case ColorAspects::TransferGamma28:
2708 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
2709 break;
2710 case ColorAspects::TransferSMPTE240M:
2711 transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
2712 break;
2713 case ColorAspects::TransferLinear:
2714 transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
2715 break;
2716 case ColorAspects::TransferXvYCC:
2717 transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
2718 break;
2719 case ColorAspects::TransferBT1361:
2720 transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
2721 break;
2722 case ColorAspects::TransferSRGB:
2723 transfer_chars = MSM_VIDC_TRANSFER_SRGB;
2724 break;
2725 default:
2726 //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2727 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
2728 break;
2729 }
2730 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
2731 case ColorAspects::MatrixUnspecified:
2732 matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
2733 break;
2734 case ColorAspects::MatrixBT709_5:
2735 matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
2736 break;
2737 case ColorAspects::MatrixBT470_6M:
2738 matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
2739 break;
2740 case ColorAspects::MatrixBT601_6:
2741 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
2742 break;
2743 case ColorAspects::MatrixSMPTE240M:
2744 transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
2745 break;
2746 case ColorAspects::MatrixBT2020:
2747 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
2748 break;
2749 case ColorAspects::MatrixBT2020Constant:
2750 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
2751 break;
2752 default:
2753 //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2754 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
2755 break;
2756 }
2757 if (!venc_set_colorspace(color_space, full_range,
2758 transfer_chars, matrix_coeffs)) {
2759
2760 DEBUG_PRINT_ERROR("Failed to set operating rate");
2761 return false;
2762 }
2763 break;
2764 }
2765 default:
2766 DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2767 break;
2768 }
2769
2770 return true;
2771 }
2772
venc_stop(void)2773 unsigned venc_dev::venc_stop( void)
2774 {
2775 struct venc_msg venc_msg;
2776 struct v4l2_requestbuffers bufreq;
2777 int rc = 0, ret = 0;
2778
2779 if (!stopped) {
2780 enum v4l2_buf_type cap_type;
2781
2782 if (streaming[OUTPUT_PORT]) {
2783 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2784 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2785
2786 if (rc) {
2787 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2788 cap_type, rc);
2789 } else
2790 streaming[OUTPUT_PORT] = false;
2791
2792 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2793 bufreq.memory = V4L2_MEMORY_USERPTR;
2794 bufreq.count = 0;
2795 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2796 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2797
2798 if (ret) {
2799 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2800 return false;
2801 }
2802 }
2803
2804 if (!rc && streaming[CAPTURE_PORT]) {
2805 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2806 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2807
2808 if (rc) {
2809 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2810 cap_type, rc);
2811 } else
2812 streaming[CAPTURE_PORT] = false;
2813
2814 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2815 bufreq.memory = V4L2_MEMORY_USERPTR;
2816 bufreq.count = 0;
2817 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2818 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2819
2820 if (ret) {
2821 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2822 return false;
2823 }
2824 }
2825
2826 if (!rc && !ret) {
2827 venc_stop_done();
2828 stopped = 1;
2829 /*set flag to re-configure when started again*/
2830 resume_in_stopped = 1;
2831
2832 }
2833 }
2834
2835 return rc;
2836 }
2837
venc_pause(void)2838 unsigned venc_dev::venc_pause(void)
2839 {
2840 pthread_mutex_lock(&pause_resume_mlock);
2841 paused = true;
2842 pthread_mutex_unlock(&pause_resume_mlock);
2843 return 0;
2844 }
2845
venc_resume(void)2846 unsigned venc_dev::venc_resume(void)
2847 {
2848 pthread_mutex_lock(&pause_resume_mlock);
2849 paused = false;
2850 pthread_mutex_unlock(&pause_resume_mlock);
2851
2852 return pthread_cond_signal(&pause_resume_cond);
2853 }
2854
venc_start_done(void)2855 unsigned venc_dev::venc_start_done(void)
2856 {
2857 struct venc_msg venc_msg;
2858 venc_msg.msgcode = VEN_MSG_START;
2859 venc_msg.statuscode = VEN_S_SUCCESS;
2860 venc_handle->async_message_process(venc_handle,&venc_msg);
2861 return 0;
2862 }
2863
venc_stop_done(void)2864 unsigned venc_dev::venc_stop_done(void)
2865 {
2866 struct venc_msg venc_msg;
2867 venc_msg.msgcode=VEN_MSG_STOP;
2868 venc_msg.statuscode=VEN_S_SUCCESS;
2869 venc_handle->async_message_process(venc_handle,&venc_msg);
2870 return 0;
2871 }
2872
venc_set_message_thread_id(pthread_t tid)2873 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2874 {
2875 async_thread_created = true;
2876 m_tid=tid;
2877 return 0;
2878 }
2879
venc_set_vqzip_defaults()2880 bool venc_dev::venc_set_vqzip_defaults()
2881 {
2882 struct v4l2_control control;
2883 int rc = 0, num_mbs_per_frame;
2884
2885 num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
2886
2887 switch (num_mbs_per_frame) {
2888 case OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT:
2889 case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
2890 case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
2891 case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
2892 break;
2893 default:
2894 DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
2895 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
2896 return false;
2897 }
2898
2899 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
2900 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
2901 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2902 if (rc)
2903 DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
2904 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
2905 control.value = INT_MAX;
2906
2907 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2908 if (rc)
2909 DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
2910
2911 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
2912 control.value = 0;
2913
2914 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2915 if (rc)
2916 DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
2917
2918 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
2919 control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
2920
2921 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2922 if (rc)
2923 DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
2924
2925 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
2926 control.value = 1;
2927
2928 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2929 if (rc)
2930 DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP");
2931
2932 return true;
2933 }
2934
2935
venc_start(void)2936 unsigned venc_dev::venc_start(void)
2937 {
2938 enum v4l2_buf_type buf_type;
2939 int ret, r;
2940 struct v4l2_control control;
2941
2942 memset(&control, 0, sizeof(control));
2943
2944 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2945 __func__);
2946 m_level_set = false;
2947
2948 if (!venc_set_profile_level(0, 0)) {
2949 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2950 __func__);
2951 } else {
2952 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2953 __func__, codec_profile.profile, profile_level.level);
2954 }
2955
2956 if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
2957 return 1;
2958
2959 // disable B-frames for realtime high-resolution/fps usecases for power considerations
2960 if (intra_period.num_bframes &&
2961 sess_priority.priority == 0 /*realtime*/ &&
2962 (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) ||
2963 (operating_rate >= 60 << 16))) {
2964 intra_period.num_pframes += (intra_period.num_bframes + 1);
2965 intra_period.num_bframes = 0;
2966 if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
2967 DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec",
2968 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16);
2969 } else {
2970 DEBUG_PRINT_ERROR("Failed to disable B frames!");
2971 }
2972 }
2973
2974 // re-configure the temporal layers as RC-mode and key-frame interval
2975 // might have changed since the client last configured the layers.
2976 if (temporal_layers_config.nPLayers) {
2977 if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2978 DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2979 } else {
2980 // request buffers on capture port again since internal (scratch)-
2981 // buffer requirements may change (i.e if we switch from non-hybrid
2982 // to hybrid mode and vice-versa)
2983 struct v4l2_requestbuffers bufreq;
2984
2985 bufreq.memory = V4L2_MEMORY_USERPTR;
2986 bufreq.count = m_sOutput_buff_property.actualcount;
2987 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2988 if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2989 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2990 }
2991 }
2992 }
2993
2994 venc_config_print();
2995
2996 if(resume_in_stopped){
2997 /*set buffercount when restarted*/
2998 venc_reconfig_reqbufs();
2999 resume_in_stopped = 0;
3000 }
3001
3002 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
3003 if (slice_mode.enable && multislice.mslice_size &&
3004 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
3005 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
3006 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
3007 MAX_SUPPORTED_SLICES_PER_FRAME);
3008 return 1;
3009 }
3010
3011 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3012 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
3013 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
3014
3015 if (ret)
3016 return 1;
3017
3018 streaming[CAPTURE_PORT] = true;
3019
3020 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
3021 control.value = 1;
3022 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3023 if (ret) {
3024 DEBUG_PRINT_ERROR("failed to request seq header");
3025 return 1;
3026 }
3027
3028
3029 stopped = 0;
3030 return 0;
3031 }
3032
hiermode_string(int val)3033 inline const char* hiermode_string(int val)
3034 {
3035 switch(val)
3036 {
3037 case HIER_NONE:
3038 return "No Hier";
3039 case HIER_P:
3040 return "Hier-P";
3041 case HIER_B:
3042 return "Hier-B";
3043 case HIER_P_HYBRID:
3044 return "Hybrid Hier-P";
3045 default:
3046 return "No hier";
3047 }
3048 }
3049
bitrate_type_string(int val)3050 inline const char* bitrate_type_string(int val)
3051 {
3052 switch(val)
3053 {
3054 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
3055 return "CUMULATIVE";
3056 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
3057 return "LAYER WISE";
3058 default:
3059 return "Unknown Bitrate Type";
3060 }
3061 }
3062
codec_as_string(unsigned long codec)3063 static const char *codec_as_string(unsigned long codec) {
3064 switch (codec) {
3065 case V4L2_PIX_FMT_H264:
3066 return "H264";
3067 case V4L2_PIX_FMT_MPEG4:
3068 return "MPEG4";
3069 case V4L2_PIX_FMT_H263:
3070 return "H263";
3071 case V4L2_PIX_FMT_HEVC:
3072 return "HEVC";
3073 case V4L2_PIX_FMT_VP8:
3074 return "VP8";
3075 default:
3076 return "UNKOWN";
3077 }
3078 }
3079
venc_config_print()3080 void venc_dev::venc_config_print()
3081 {
3082
3083 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
3084 codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
3085
3086 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
3087 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
3088 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3089
3090 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
3091 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
3092 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
3093
3094 DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
3095 color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
3096
3097 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
3098 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
3099
3100 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
3101 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
3102
3103 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
3104 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
3105
3106 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
3107 session_qp_values.minqp, session_qp_values.maxqp);
3108
3109 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
3110 voptimecfg.voptime_resolution, multislice.mslice_mode,
3111 multislice.mslice_size);
3112
3113 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
3114 entropy.longentropysel, entropy.cabacmodel);
3115
3116 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
3117 dbkfilter.db_mode, dbkfilter.slicealpha_offset,
3118 dbkfilter.slicebeta_offset);
3119
3120 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
3121 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
3122
3123 DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
3124 ltrinfo.enabled, ltrinfo.count);
3125
3126 if (temporal_layers_config.nPLayers) {
3127 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
3128 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
3129 intra_period.num_pframes + intra_period.num_bframes + 1);
3130
3131 for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
3132 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
3133 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
3134 l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
3135 }
3136 } else {
3137
3138 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
3139 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
3140
3141 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
3142 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
3143
3144 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
3145 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
3146 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
3147 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
3148 }
3149
3150 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
3151
3152 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
3153
3154 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
3155
3156 DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
3157
3158 DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
3159 }
3160
venc_reconfig_reqbufs()3161 bool venc_dev::venc_reconfig_reqbufs()
3162 {
3163 struct v4l2_requestbuffers bufreq;
3164
3165 bufreq.memory = V4L2_MEMORY_USERPTR;
3166 bufreq.count = m_sInput_buff_property.actualcount;
3167 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3168 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3169 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
3170 return false;
3171 }
3172
3173 bufreq.memory = V4L2_MEMORY_USERPTR;
3174 bufreq.count = m_sOutput_buff_property.actualcount;
3175 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3176 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
3177 {
3178 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
3179 return false;
3180 }
3181 return true;
3182 }
3183
venc_flush(unsigned port)3184 unsigned venc_dev::venc_flush( unsigned port)
3185 {
3186 struct v4l2_encoder_cmd enc;
3187 DEBUG_PRINT_LOW("in %s", __func__);
3188
3189 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
3190 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3191
3192 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
3193 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
3194 return -1;
3195 }
3196
3197 return 0;
3198
3199 }
3200
3201 //allocating I/P memory from pmem and register with the device
3202
3203
venc_use_buf(void * buf_addr,unsigned port,unsigned index)3204 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
3205 {
3206
3207 struct pmem *pmem_tmp;
3208 struct v4l2_buffer buf;
3209 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3210 int rc = 0;
3211 unsigned int extra_idx;
3212
3213 pmem_tmp = (struct pmem *)buf_addr;
3214 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
3215
3216 if (port == PORT_INDEX_OUT) {
3217 extra_idx = EXTRADATA_IDX(num_output_planes);
3218 buf.index = index;
3219 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3220 buf.memory = V4L2_MEMORY_USERPTR;
3221 plane[0].length = pmem_tmp->size;
3222 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
3223 plane[0].reserved[0] = pmem_tmp->fd;
3224 plane[0].reserved[1] = 0;
3225 plane[0].data_offset = pmem_tmp->offset;
3226 buf.m.planes = plane;
3227 buf.length = num_output_planes;
3228
3229 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3230 char *userptr;
3231 int fd;
3232 unsigned offset;
3233 ssize_t size;
3234 int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size);
3235 if (rc != OMX_ErrorNone) {
3236 DEBUG_PRINT_ERROR("Unable to get extradata memory 2");
3237 return rc;
3238 }
3239 plane[extra_idx].length = size;
3240 plane[extra_idx].m.userptr = (unsigned long)userptr;
3241 #ifdef USE_ION
3242 plane[extra_idx].reserved[0] = fd;
3243 #endif
3244 plane[extra_idx].reserved[1] = offset;
3245 plane[extra_idx].data_offset = 0;
3246 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3247 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
3248 return OMX_ErrorBadParameter;
3249 }
3250
3251 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
3252
3253 if (rc)
3254 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
3255 } else if (port == PORT_INDEX_IN) {
3256 DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port");
3257 } else {
3258 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
3259 return false;
3260 }
3261
3262 return true;
3263 }
3264
venc_free_buf(void * buf_addr,unsigned port)3265 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
3266 {
3267 struct pmem *pmem_tmp;
3268 struct venc_bufferpayload dev_buffer;
3269
3270 memset(&dev_buffer, 0, sizeof(dev_buffer));
3271 pmem_tmp = (struct pmem *)buf_addr;
3272
3273 if (port == PORT_INDEX_IN) {
3274 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3275 dev_buffer.fd = pmem_tmp->fd;
3276 dev_buffer.maped_size = pmem_tmp->size;
3277 dev_buffer.sz = pmem_tmp->size;
3278 dev_buffer.offset = pmem_tmp->offset;
3279 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3280 dev_buffer.pbuffer, \
3281 dev_buffer.fd, \
3282 dev_buffer.offset, \
3283 dev_buffer.maped_size);
3284
3285 } else if (port == PORT_INDEX_OUT) {
3286 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
3287 dev_buffer.fd = pmem_tmp->fd;
3288 dev_buffer.sz = pmem_tmp->size;
3289 dev_buffer.maped_size = pmem_tmp->size;
3290 dev_buffer.offset = pmem_tmp->offset;
3291
3292 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
3293 dev_buffer.pbuffer, \
3294 dev_buffer.fd, \
3295 dev_buffer.offset, \
3296 dev_buffer.maped_size);
3297 } else {
3298 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
3299 return false;
3300 }
3301
3302 return true;
3303 }
3304
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3305 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
3306 OMX_U32 width, OMX_U32 height)
3307 {
3308 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
3309 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
3310 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
3311 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
3312 src_chroma_offset = width * height;
3313
3314 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
3315 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3316 //Do chroma first, so that we can convert it in-place
3317 src_buf += width * height;
3318 dst_buf += y_stride * y_scanlines;
3319 for (int line = height / 2 - 1; line >= 0; --line) {
3320 memmove(dst_buf + line * uv_stride,
3321 src_buf + line * width,
3322 width);
3323 }
3324
3325 dst_buf = src_buf = buffer->pBuffer;
3326 //Copy the Y next
3327 for (int line = height - 1; line > 0; --line) {
3328 memmove(dst_buf + line * y_stride,
3329 src_buf + line * width,
3330 width);
3331 }
3332 } else {
3333 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3334 Insufficient bufferLen=%u v/s Required=%u",
3335 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3336 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3337 return false;
3338 }
3339
3340 return true;
3341 }
3342
venc_get_performance_level(OMX_U32 * perflevel)3343 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
3344 {
3345 if (!perflevel) {
3346 DEBUG_PRINT_ERROR("Null pointer error");
3347 return false;
3348 } else {
3349 *perflevel = performance_level.perflevel;
3350 return true;
3351 }
3352 }
3353
venc_get_vui_timing_info(OMX_U32 * enabled)3354 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
3355 {
3356 if (!enabled) {
3357 DEBUG_PRINT_ERROR("Null pointer error");
3358 return false;
3359 } else {
3360 *enabled = vui_timing_info.enabled;
3361 return true;
3362 }
3363 }
3364
venc_get_vqzip_sei_info(OMX_U32 * enabled)3365 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
3366 {
3367 if (!enabled) {
3368 DEBUG_PRINT_ERROR("Null pointer error");
3369 return false;
3370 } else {
3371 *enabled = vqzip_sei_info.enabled;
3372 return true;
3373 }
3374 }
3375
venc_get_peak_bitrate(OMX_U32 * peakbitrate)3376 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
3377 {
3378 if (!peakbitrate) {
3379 DEBUG_PRINT_ERROR("Null pointer error");
3380 return false;
3381 } else {
3382 *peakbitrate = peak_bitrate.peakbitrate;
3383 return true;
3384 }
3385 }
3386
venc_get_batch_size(OMX_U32 * size)3387 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
3388 {
3389 if (!size) {
3390 DEBUG_PRINT_ERROR("Null pointer error");
3391 return false;
3392 } else {
3393 *size = mBatchSize;
3394 return true;
3395 }
3396 }
3397
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3398 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
3399 {
3400 struct pmem *temp_buffer;
3401 struct v4l2_buffer buf;
3402 struct v4l2_requestbuffers bufreq;
3403 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3404 int rc = 0, extra_idx;
3405 struct OMX_BUFFERHEADERTYPE *bufhdr;
3406 encoder_media_buffer_type * meta_buf = NULL;
3407 temp_buffer = (struct pmem *)buffer;
3408
3409 memset (&buf, 0, sizeof(buf));
3410 memset (&plane, 0, sizeof(plane));
3411
3412 if (buffer == NULL) {
3413 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
3414 return false;
3415 }
3416
3417 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3418 bufreq.memory = V4L2_MEMORY_USERPTR;
3419 bufreq.count = m_sInput_buff_property.actualcount;
3420 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3421
3422 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
3423
3424 if (pmem_data_buf) {
3425 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
3426 plane[0].m.userptr = (unsigned long)pmem_data_buf;
3427 plane[0].data_offset = bufhdr->nOffset;
3428 plane[0].length = bufhdr->nAllocLen;
3429 plane[0].bytesused = bufhdr->nFilledLen;
3430 } else {
3431 // --------------------------------------------------------------------------------------
3432 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info]
3433 // ---------------------------------------------------------------------------------------
3434 // Camera-2 1 CameraSource 0 meta-handle
3435 // Camera-3 1 GrallocSource 0 gralloc-private-handle
3436 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted)
3437 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr
3438 // ---------------------------------------------------------------------------------------
3439 if (metadatamode) {
3440 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3441 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3442
3443 if (!meta_buf) {
3444 //empty EOS buffer
3445 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
3446 plane[0].data_offset = bufhdr->nOffset;
3447 plane[0].length = bufhdr->nAllocLen;
3448 plane[0].bytesused = bufhdr->nFilledLen;
3449 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
3450 } else {
3451 return false;
3452 }
3453 } else if (!color_format) {
3454 int usage = 0;
3455
3456 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3457 native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
3458 if (!hnd) {
3459 DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
3460 return false;
3461 }
3462
3463 if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
3464 usage = hnd->data[3];
3465 } else if (mBatchSize) {
3466 usage = BatchInfo::getColorFormatAt(hnd, 0);
3467 }
3468 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
3469 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3470 }
3471
3472 if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
3473 m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
3474 struct v4l2_format fmt;
3475
3476 memset(&fmt, 0, sizeof(fmt));
3477 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
3478 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
3479 DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
3480 DEBUG_PRINT_ERROR(" This leads to unknown color space");
3481 }
3482 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
3483 if (is_csc_enabled) {
3484 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3485 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3486 venc_set_colorspace(MSM_VIDC_BT709_5, 1,
3487 MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
3488 } else {
3489 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
3490 MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3491 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3492 }
3493 }
3494 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3495 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3496 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3497 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3498 if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
3499 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
3500 }
3501 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3502 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3503 DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
3504 return false;
3505 }
3506 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3507 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3508 return false;
3509 }
3510 }
3511
3512 // Setting batch mode is sticky. We do not expect camera to change
3513 // between batch and normal modes at runtime.
3514 if (mBatchSize) {
3515 if ((unsigned)hnd->numFds != mBatchSize) {
3516 DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
3517 mBatchSize, hnd->numFds);
3518 return false;
3519 }
3520
3521 return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
3522 }
3523
3524 if (hnd->numFds + hnd->numInts > 2) {
3525 plane[0].data_offset = hnd->data[1];
3526 plane[0].length = hnd->data[2];
3527 plane[0].bytesused = hnd->data[2];
3528 }
3529 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
3530 fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
3531 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
3532 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
3533
3534 if (!handle) {
3535 DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
3536 return false;
3537 }
3538
3539 if (mUseAVTimerTimestamps) {
3540 uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
3541 if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
3542 && avTimerTimestampNs > 0) {
3543 bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
3544 DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
3545 }
3546 }
3547
3548 if (!streaming[OUTPUT_PORT]) {
3549 // Moment of truth... actual colorspace is known here..
3550 ColorSpace_t colorSpace = ITU_R_601;
3551 if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
3552 DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3553 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3554 }
3555
3556 struct v4l2_format fmt;
3557 memset(&fmt, 0, sizeof(fmt));
3558 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3559
3560 bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
3561 if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3562 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
3563 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
3564 } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
3565 // In case of RGB, conversion to YUV is handled within encoder.
3566 // Disregard the Colorspace in gralloc-handle in case of RGB and use
3567 // [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
3568 // [b] 601 for UBWC case : Venus can convert to 601-LR or FR. use LR for now.
3569 colorSpace = ITU_R_601;
3570 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
3571 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
3572 } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3573 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3574 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
3575 }
3576
3577 // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
3578 if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
3579 struct v4l2_control control;
3580 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
3581 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
3582 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3583 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
3584 } else {
3585 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
3586 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
3587 colorSpace = ITU_R_709;
3588 }
3589 }
3590
3591 msm_vidc_h264_color_primaries_values primary;
3592 msm_vidc_h264_transfer_chars_values transfer;
3593 msm_vidc_h264_matrix_coeff_values matrix;
3594 OMX_U32 range;
3595
3596 switch (colorSpace) {
3597 case ITU_R_601_FR:
3598 {
3599 primary = MSM_VIDC_BT601_6_525;
3600 range = 1; // full
3601 transfer = MSM_VIDC_TRANSFER_601_6_525;
3602 matrix = MSM_VIDC_MATRIX_601_6_525;
3603
3604 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3605 break;
3606 }
3607 case ITU_R_709:
3608 {
3609 primary = MSM_VIDC_BT709_5;
3610 range = 0; // limited
3611 transfer = MSM_VIDC_TRANSFER_BT709_5;
3612 matrix = MSM_VIDC_MATRIX_BT_709_5;
3613
3614 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
3615 break;
3616 }
3617 default:
3618 {
3619 // 601 or something else ? assume 601
3620 primary = MSM_VIDC_BT601_6_625;
3621 range = 0; //limited
3622 transfer = MSM_VIDC_TRANSFER_601_6_625;
3623 matrix = MSM_VIDC_MATRIX_601_6_625;
3624
3625 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
3626 break;
3627 }
3628 }
3629 DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
3630 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
3631 venc_set_colorspace(primary, range, transfer, matrix);
3632
3633 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3634 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3635 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3636 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3637 DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
3638 return false;
3639 }
3640 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3641 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
3642 return false;
3643 }
3644 }
3645
3646 fd = handle->fd;
3647 plane[0].data_offset = 0;
3648 plane[0].length = handle->size;
3649 plane[0].bytesused = handle->size;
3650 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
3651 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
3652 }
3653 } else {
3654 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3655 plane[0].data_offset = bufhdr->nOffset;
3656 plane[0].length = bufhdr->nAllocLen;
3657 plane[0].bytesused = bufhdr->nFilledLen;
3658 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
3659 fd, plane[0].bytesused, plane[0].length);
3660 }
3661 } else {
3662 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3663 plane[0].data_offset = bufhdr->nOffset;
3664 plane[0].length = bufhdr->nAllocLen;
3665 plane[0].bytesused = bufhdr->nFilledLen;
3666 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
3667 fd, plane[0].bytesused, plane[0].length);
3668 }
3669 }
3670
3671 extra_idx = EXTRADATA_IDX(num_input_planes);
3672
3673 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3674 char *userptr;
3675 int fd;
3676 unsigned offset;
3677 ssize_t size;
3678 int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
3679 if (rc != OMX_ErrorNone) {
3680 DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
3681 return rc;
3682 }
3683 plane[extra_idx].bytesused = 0;
3684 plane[extra_idx].length = size;
3685 plane[extra_idx].m.userptr = (unsigned long) userptr;
3686 #ifdef USE_ION
3687 plane[extra_idx].reserved[0] = fd;
3688 #endif
3689 plane[extra_idx].reserved[1] = offset;
3690 plane[extra_idx].data_offset = 0;
3691 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3692 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3693 return false;
3694 }
3695
3696 if (!streaming[OUTPUT_PORT]) {
3697 enum v4l2_buf_type buf_type;
3698 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3699 int ret;
3700 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3701
3702 if (ret) {
3703 DEBUG_PRINT_ERROR("Failed to call streamon");
3704 if (errno == EBUSY) {
3705 hw_overload = true;
3706 }
3707 return false;
3708 } else {
3709 streaming[OUTPUT_PORT] = true;
3710 }
3711 }
3712
3713 buf.index = index;
3714 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3715 buf.memory = V4L2_MEMORY_USERPTR;
3716 plane[0].reserved[0] = fd;
3717 plane[0].reserved[1] = 0;
3718 buf.m.planes = plane;
3719 buf.length = num_input_planes;
3720
3721 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3722 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3723
3724 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3725 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3726 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3727
3728 if (rc) {
3729 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3730 return false;
3731 }
3732
3733 etb++;
3734
3735 if (m_debug.in_buffer_log) {
3736 venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
3737 }
3738
3739 return true;
3740 }
3741
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3742 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3743 {
3744 struct v4l2_buffer buf;
3745 struct v4l2_plane plane;
3746 int rc = 0;
3747 struct v4l2_control control;
3748 encoder_media_buffer_type * meta_buf = NULL;
3749 native_handle_t *hnd = NULL;
3750
3751 if (bufhdr == NULL) {
3752 DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3753 return false;
3754 }
3755
3756 bool status = true;
3757 if (metadatamode) {
3758 plane.m.userptr = (unsigned long)bufhdr->pBuffer;
3759 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3760
3761 if (!color_format) {
3762 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3763 hnd = (native_handle_t*)meta_buf->meta_handle;
3764 if (!hnd) {
3765 DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3766 return false;
3767 } else if (hnd->numFds > kMaxBuffersInBatch) {
3768 DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3769 "Max = %d", hnd->numFds, kMaxBuffersInBatch);
3770 status = false;
3771 }
3772 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
3773 } else {
3774 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3775 status = false;
3776 }
3777 } else {
3778 DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3779 status = false;
3780 }
3781 } else {
3782 DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3783 status = false;
3784 }
3785
3786 if (status) {
3787 OMX_TICKS bufTimeStamp = 0ll;
3788 int numBufs = hnd->numFds;
3789 int v4l2Ids[kMaxBuffersInBatch] = {-1};
3790 for (int i = 0; i < numBufs; ++i) {
3791 v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3792 if (v4l2Ids[i] < 0) {
3793 DEBUG_PRINT_ERROR("Failed to register buffer");
3794 // TODO: cleanup the map and purge all slots of current index
3795 status = false;
3796 break;
3797 }
3798 }
3799 for (int i = 0; i < numBufs; ++i) {
3800 int v4l2Id = v4l2Ids[i];
3801
3802 memset(&buf, 0, sizeof(buf));
3803 memset(&plane, 0, sizeof(plane));
3804
3805 DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3806 buf.index = (unsigned)v4l2Id;
3807 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3808 buf.memory = V4L2_MEMORY_USERPTR;
3809 plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
3810 plane.reserved[1] = 0;
3811 plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
3812 plane.m.userptr = (unsigned long)meta_buf;
3813 plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
3814 buf.m.planes = &plane;
3815 buf.length = 1;
3816
3817 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3818 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3819 if (i != numBufs - 1) {
3820 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3821 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
3822 i, etb + 1, numBufs);
3823 }
3824
3825
3826 // timestamp differences from camera are in nano-seconds
3827 bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
3828
3829 DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3830 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
3831 buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3832 buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3833
3834 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3835 if (rc) {
3836 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3837 return false;
3838 }
3839
3840 etb++;
3841 }
3842 }
3843
3844 if (status && !streaming[OUTPUT_PORT]) {
3845 enum v4l2_buf_type buf_type;
3846 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3847 int ret;
3848 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3849 if (ret) {
3850 DEBUG_PRINT_ERROR("Failed to call streamon");
3851 if (errno == EBUSY) {
3852 hw_overload = true;
3853 }
3854 status = false;
3855 } else {
3856 streaming[OUTPUT_PORT] = true;
3857 }
3858 }
3859
3860 return status;
3861 }
3862
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3863 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3864 {
3865 struct pmem *temp_buffer = NULL;
3866 struct venc_buffer frameinfo;
3867 struct v4l2_buffer buf;
3868 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3869 int rc = 0;
3870 unsigned int extra_idx;
3871 struct OMX_BUFFERHEADERTYPE *bufhdr;
3872
3873 if (buffer == NULL)
3874 return false;
3875
3876 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3877
3878 if (pmem_data_buf) {
3879 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3880 plane[0].m.userptr = (unsigned long)pmem_data_buf;
3881 } else {
3882 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3883 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3884 }
3885
3886 memset(&buf, 0, sizeof(buf));
3887 memset(&plane, 0, sizeof(plane));
3888
3889 buf.index = index;
3890 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3891 buf.memory = V4L2_MEMORY_USERPTR;
3892 plane[0].length = bufhdr->nAllocLen;
3893 plane[0].bytesused = bufhdr->nFilledLen;
3894 plane[0].reserved[0] = fd;
3895 plane[0].reserved[1] = 0;
3896 plane[0].data_offset = bufhdr->nOffset;
3897 buf.m.planes = plane;
3898 buf.length = num_output_planes;
3899 buf.flags = 0;
3900
3901 if (mBatchSize) {
3902 // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
3903 // This results in the first batch being of size mBatchSize + 1, but thats good because
3904 // we need an extra FTB for the codec specific data.
3905
3906 if (!ftb || ftb % mBatchSize) {
3907 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3908 DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
3909 }
3910 }
3911
3912 extra_idx = EXTRADATA_IDX(num_output_planes);
3913
3914 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3915 char *userptr;
3916 int fd;
3917 unsigned offset;
3918 ssize_t size;
3919 int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
3920 if (rc != OMX_ErrorNone) {
3921 DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
3922 return false;
3923 }
3924 plane[extra_idx].bytesused = 0;
3925 plane[extra_idx].length = size;
3926 plane[extra_idx].m.userptr = (unsigned long)userptr;
3927 #ifdef USE_ION
3928 plane[extra_idx].reserved[0] = fd;
3929 #endif
3930 plane[extra_idx].reserved[1] = offset;
3931 plane[extra_idx].data_offset = 0;
3932 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3933 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3934 return false;
3935 }
3936
3937 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3938
3939 if (rc) {
3940 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3941 return false;
3942 }
3943
3944 ftb++;
3945 return true;
3946 }
3947
venc_set_inband_video_header(OMX_BOOL enable)3948 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
3949 {
3950 struct v4l2_control control;
3951
3952 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
3953 if(enable) {
3954 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
3955 } else {
3956 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
3957 }
3958
3959 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
3960 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3961 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
3962 return false;
3963 }
3964 return true;
3965 }
3966
venc_set_au_delimiter(OMX_BOOL enable)3967 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
3968 {
3969 struct v4l2_control control;
3970
3971 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
3972 if(enable) {
3973 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
3974 } else {
3975 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
3976 }
3977
3978 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
3979 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3980 DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
3981 return false;
3982 }
3983 return true;
3984 }
3985
venc_set_mbi_statistics_mode(OMX_U32 mode)3986 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
3987 {
3988 struct v4l2_control control;
3989
3990 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
3991 control.value = mode;
3992
3993 DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
3994 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3995 DEBUG_PRINT_ERROR("Setting MBI mode failed");
3996 return false;
3997 }
3998 return true;
3999 }
4000
venc_set_vqzip_sei_type(OMX_BOOL enable)4001 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
4002 {
4003 struct v4l2_control sei_control, yuvstats_control;
4004
4005 DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
4006 sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
4007 yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4008
4009 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
4010 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
4011 }
4012
4013 if(enable) {
4014 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
4015 yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4016 } else {
4017 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
4018 yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4019 }
4020
4021 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
4022 DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
4023 }
4024
4025 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
4026 DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
4027 }
4028 #ifdef _VQZIP_
4029 vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
4030 vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
4031 vqzip.init();
4032 vqzip_sei_info.enabled = true;
4033 #endif
4034
4035 return true;
4036 }
4037
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)4038 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
4039 {
4040 // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
4041 if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
4042 return false;
4043
4044 // Check for bframes with Hier-P-Hybrid
4045 if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
4046 return false;
4047
4048 // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
4049 if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
4050 hier_layers.hier_mode == HIER_B || ltrinfo.count))
4051 return false;
4052
4053 // Check for LTR with Hier-P-Hybrid
4054 if (count && hier_layers.hier_mode == HIER_P_HYBRID)
4055 return false;
4056
4057 return true;
4058 }
4059
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)4060 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
4061 OMX_U32 num_layers)
4062 {
4063 struct v4l2_control control;
4064
4065 if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
4066 DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
4067 return false;
4068 }
4069
4070 if (type == QOMX_HIERARCHICALCODING_P) {
4071 // Reduce layer count by 1 before sending to driver. This avoids
4072 // driver doing the same in multiple places.
4073 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
4074 control.value = num_layers - 1;
4075 DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
4076 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4077 DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
4078 return false;
4079 }
4080 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
4081 control.value = num_layers - 1;
4082 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
4083 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4084 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4085 return false;
4086 }
4087 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4088 DEBUG_PRINT_LOW("Set H264_SVC_NAL");
4089 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4090 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4091 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4092 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4093 return false;
4094 }
4095 }
4096 hier_layers.hier_mode = HIER_P;
4097 } else if (type == QOMX_HIERARCHICALCODING_B) {
4098 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4099 DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
4100 return false;
4101 }
4102 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
4103 control.value = num_layers - 1;
4104 DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
4105 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4106 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4107 return false;
4108 }
4109 hier_layers.hier_mode = HIER_B;
4110 } else {
4111 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
4112 return false;
4113 }
4114 hier_layers.numlayers = num_layers;
4115 return true;
4116 }
4117
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)4118 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
4119 {
4120 struct v4l2_control control;
4121
4122 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
4123
4124 if (enable == OMX_FALSE) {
4125 /* No easy way to turn off extradata to the driver
4126 * at the moment */
4127 return false;
4128 }
4129
4130 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4131 switch (extra_data) {
4132 case OMX_ExtraDataVideoEncoderSliceInfo:
4133 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
4134 break;
4135 case OMX_ExtraDataVideoEncoderMBInfo:
4136 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
4137 break;
4138 case OMX_ExtraDataFrameDimension:
4139 control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
4140 break;
4141 default:
4142 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
4143 return false;
4144 }
4145
4146 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4147 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
4148 (unsigned int)extra_data, errno);
4149 return false;
4150 }
4151
4152 return true;
4153 }
4154
venc_set_slice_delivery_mode(OMX_U32 enable)4155 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
4156 {
4157 struct v4l2_control control;
4158
4159 if (enable) {
4160 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
4161 control.value = 1;
4162 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
4163
4164 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4165 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4166 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
4167 return false;
4168 } else {
4169 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
4170 slice_mode.enable = 1;
4171 }
4172 } else {
4173 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
4174 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
4175 m_sVenc_cfg.codectype);
4176 }
4177 } else {
4178 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
4179 }
4180
4181 return true;
4182 }
4183
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)4184 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
4185 {
4186 int rc;
4187 struct v4l2_control control;
4188 struct v4l2_ext_control ctrl[4];
4189 struct v4l2_ext_controls controls;
4190
4191 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
4192 ctrl[0].value = initqp->nQpI;
4193 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
4194 ctrl[1].value = initqp->nQpP;
4195 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
4196 ctrl[2].value = initqp->nQpB;
4197 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
4198 ctrl[3].value = initqp->bEnableInitQp;
4199
4200 controls.count = 4;
4201 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4202 controls.controls = ctrl;
4203
4204 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4205 controls.controls[0].id, controls.controls[0].value,
4206 controls.controls[1].id, controls.controls[1].value,
4207 controls.controls[2].id, controls.controls[2].value,
4208 controls.controls[3].id, controls.controls[3].value);
4209
4210 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4211 if (rc) {
4212 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
4213 return false;
4214 }
4215
4216 init_qp.iframeqp = initqp->nQpI;
4217 init_qp.pframeqp = initqp->nQpP;
4218 init_qp.bframeqp = initqp->nQpB;
4219 init_qp.enableinitqp = initqp->bEnableInitQp;
4220
4221 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4222 controls.controls[0].id, controls.controls[0].value,
4223 controls.controls[1].id, controls.controls[1].value,
4224 controls.controls[2].id, controls.controls[2].value,
4225 controls.controls[3].id, controls.controls[3].value);
4226 return true;
4227 }
4228
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)4229 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
4230 OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
4231 {
4232 int rc;
4233 struct v4l2_control control;
4234
4235 DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
4236 primaries, range, transfer_chars, matrix_coeffs);
4237
4238 control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
4239 control.value = primaries;
4240
4241 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4242 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4243
4244 if (rc) {
4245 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
4246 return false;
4247 }
4248
4249 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4250
4251 color_space.primaries = control.value;
4252
4253 control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
4254 control.value = range;
4255
4256 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4257 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4258
4259 if (rc) {
4260 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
4261 return false;
4262 }
4263
4264 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4265
4266 color_space.range = control.value;
4267
4268 control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
4269 control.value = transfer_chars;
4270
4271 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4272 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4273
4274 if (rc) {
4275 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
4276 return false;
4277 }
4278
4279 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4280
4281 color_space.transfer_chars = control.value;
4282
4283 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
4284 control.value = matrix_coeffs;
4285
4286 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4287 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4288
4289 if (rc) {
4290 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
4291 return false;
4292 }
4293
4294 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4295
4296 color_space.matrix_coeffs = control.value;
4297
4298 return true;
4299 }
4300
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)4301 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
4302 {
4303 int rc;
4304 struct v4l2_control control;
4305
4306 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
4307 control.value = i_frame_qp;
4308
4309 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4310 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4311
4312 if (rc) {
4313 DEBUG_PRINT_ERROR("Failed to set control");
4314 return false;
4315 }
4316
4317 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4318 session_qp.iframeqp = control.value;
4319
4320 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
4321 control.value = p_frame_qp;
4322
4323 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4324 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4325
4326 if (rc) {
4327 DEBUG_PRINT_ERROR("Failed to set control");
4328 return false;
4329 }
4330
4331 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4332
4333 session_qp.pframeqp = control.value;
4334
4335 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
4336 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4337
4338 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
4339 control.value = b_frame_qp;
4340
4341 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4342 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4343
4344 if (rc) {
4345 DEBUG_PRINT_ERROR("Failed to set control");
4346 return false;
4347 }
4348
4349 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4350
4351 session_qp.bframeqp = control.value;
4352 }
4353
4354 return true;
4355 }
4356
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)4357 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
4358 {
4359 int rc;
4360 struct v4l2_control control;
4361
4362 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
4363
4364 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4365 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
4366 else
4367 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
4368 control.value = min_qp;
4369
4370 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
4371 control.id, control.value);
4372 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4373 if (rc) {
4374 DEBUG_PRINT_ERROR("Failed to set control");
4375 return false;
4376 }
4377
4378 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4379 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
4380 else
4381 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
4382 control.value = max_qp;
4383
4384 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
4385 control.id, control.value);
4386 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4387 if (rc) {
4388 DEBUG_PRINT_ERROR("Failed to set control");
4389 return false;
4390 }
4391 } else {
4392 DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
4393 (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
4394 }
4395
4396 return true;
4397 }
4398
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)4399 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
4400 {
4401 struct venc_profile requested_profile = {0};
4402 struct ven_profilelevel requested_level = {0};
4403 unsigned long mb_per_frame = 0;
4404 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
4405 (unsigned int)eProfile, (unsigned int)eLevel);
4406 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4407 ((m_sVenc_cfg.dvs_width + 15) >> 4);
4408
4409 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
4410 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
4411 return true;
4412 }
4413
4414 if (vqzip_sei_info.enabled) {
4415 DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
4416 return true;
4417 }
4418
4419 DEBUG_PRINT_LOW("Validating Profile/Level from table");
4420
4421 if (!venc_validate_profile_level(&eProfile, &eLevel)) {
4422 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
4423 return false;
4424 }
4425
4426 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4427 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
4428 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
4429 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
4430
4431 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4432 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
4433 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4434 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
4435 } else {
4436 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
4437 (unsigned int)eProfile);
4438 return false;
4439 }
4440
4441 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
4442 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
4443 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
4444 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
4445
4446 if (mb_per_frame >= 3600) {
4447 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4448 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4449
4450 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4451 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4452 } else {
4453 switch (eLevel) {
4454 case OMX_VIDEO_MPEG4Level0:
4455 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
4456 break;
4457 case OMX_VIDEO_MPEG4Level0b:
4458 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
4459 break;
4460 case OMX_VIDEO_MPEG4Level1:
4461 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
4462 break;
4463 case OMX_VIDEO_MPEG4Level2:
4464 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
4465 break;
4466 case OMX_VIDEO_MPEG4Level3:
4467 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
4468 break;
4469 case OMX_VIDEO_MPEG4Level4a:
4470 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
4471 break;
4472 case OMX_VIDEO_MPEG4Level5:
4473 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4474 break;
4475 default:
4476 return false;
4477 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
4478 break;
4479 }
4480 }
4481 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4482
4483 switch (eProfile) {
4484 case OMX_VIDEO_H263ProfileBaseline:
4485 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
4486 break;
4487 case OMX_VIDEO_H263ProfileH320Coding:
4488 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
4489 break;
4490 case OMX_VIDEO_H263ProfileBackwardCompatible:
4491 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
4492 break;
4493 case OMX_VIDEO_H263ProfileISWV2:
4494 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
4495 break;
4496 case OMX_VIDEO_H263ProfileISWV3:
4497 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
4498 break;
4499 case OMX_VIDEO_H263ProfileHighCompression:
4500 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
4501 break;
4502 case OMX_VIDEO_H263ProfileInternet:
4503 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
4504 break;
4505 case OMX_VIDEO_H263ProfileInterlace:
4506 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
4507 break;
4508 case OMX_VIDEO_H263ProfileHighLatency:
4509 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
4510 break;
4511 default:
4512 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
4513 requested_profile.profile);
4514 return false;
4515 }
4516
4517 //profile level
4518 switch (eLevel) {
4519 case OMX_VIDEO_H263Level10:
4520 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
4521 break;
4522 case OMX_VIDEO_H263Level20:
4523 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
4524 break;
4525 case OMX_VIDEO_H263Level30:
4526 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
4527 break;
4528 case OMX_VIDEO_H263Level40:
4529 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
4530 break;
4531 case OMX_VIDEO_H263Level45:
4532 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
4533 break;
4534 case OMX_VIDEO_H263Level50:
4535 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
4536 break;
4537 case OMX_VIDEO_H263Level60:
4538 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
4539 break;
4540 case OMX_VIDEO_H263Level70:
4541 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
4542 break;
4543 default:
4544 return false;
4545 break;
4546 }
4547 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4548 if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
4549 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
4550 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
4551 eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
4552 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
4553 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh ||
4554 eProfile == OMX_VIDEO_AVCProfileConstrainedHigh) {
4555 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
4556 } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
4557 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
4558 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
4559 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
4560 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
4561 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
4562 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
4563 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
4564 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
4565 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
4566 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
4567 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
4568 } else {
4569 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
4570 requested_profile.profile);
4571 return false;
4572 }
4573
4574 //profile level
4575 switch (eLevel) {
4576 case OMX_VIDEO_AVCLevel1:
4577 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
4578 break;
4579 case OMX_VIDEO_AVCLevel1b:
4580 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
4581 break;
4582 case OMX_VIDEO_AVCLevel11:
4583 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
4584 break;
4585 case OMX_VIDEO_AVCLevel12:
4586 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
4587 break;
4588 case OMX_VIDEO_AVCLevel13:
4589 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
4590 break;
4591 case OMX_VIDEO_AVCLevel2:
4592 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
4593 break;
4594 case OMX_VIDEO_AVCLevel21:
4595 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
4596 break;
4597 case OMX_VIDEO_AVCLevel22:
4598 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
4599 break;
4600 case OMX_VIDEO_AVCLevel3:
4601 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
4602 break;
4603 case OMX_VIDEO_AVCLevel31:
4604 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
4605 break;
4606 case OMX_VIDEO_AVCLevel32:
4607 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
4608 break;
4609 case OMX_VIDEO_AVCLevel4:
4610 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
4611 break;
4612 case OMX_VIDEO_AVCLevel41:
4613 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
4614 break;
4615 case OMX_VIDEO_AVCLevel42:
4616 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
4617 break;
4618 case OMX_VIDEO_AVCLevel5:
4619 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
4620 break;
4621 case OMX_VIDEO_AVCLevel51:
4622 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
4623 break;
4624 case OMX_VIDEO_AVCLevel52:
4625 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4626 break;
4627 case OMX_VIDEO_AVCLevelMax:
4628 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4629 break;
4630 default :
4631 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
4632 requested_level.level);
4633 return false;
4634 break;
4635 }
4636 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4637 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
4638 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
4639 (unsigned int)eProfile);
4640 return false;
4641 }
4642 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
4643 m_profile_set = true;
4644 switch(eLevel) {
4645 case OMX_VIDEO_VP8Level_Version0:
4646 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
4647 break;
4648 case OMX_VIDEO_VP8Level_Version1:
4649 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
4650 break;
4651 default:
4652 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
4653 (unsigned int)eLevel);
4654 return false;
4655 break;
4656 }
4657 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4658 if (eProfile == OMX_VIDEO_HEVCProfileMain) {
4659 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
4660 } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
4661 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
4662 } else {
4663 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
4664 requested_profile.profile);
4665 return false;
4666 }
4667
4668 //profile level
4669 switch (eLevel) {
4670 case OMX_VIDEO_HEVCMainTierLevel1:
4671 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
4672 break;
4673 case OMX_VIDEO_HEVCHighTierLevel1:
4674 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
4675 break;
4676 case OMX_VIDEO_HEVCMainTierLevel2:
4677 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
4678 break;
4679 case OMX_VIDEO_HEVCHighTierLevel2:
4680 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
4681 break;
4682 case OMX_VIDEO_HEVCMainTierLevel21:
4683 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
4684 break;
4685 case OMX_VIDEO_HEVCHighTierLevel21:
4686 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
4687 break;
4688 case OMX_VIDEO_HEVCMainTierLevel3:
4689 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
4690 break;
4691 case OMX_VIDEO_HEVCHighTierLevel3:
4692 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
4693 break;
4694 case OMX_VIDEO_HEVCMainTierLevel31:
4695 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
4696 break;
4697 case OMX_VIDEO_HEVCHighTierLevel31:
4698 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
4699 break;
4700 case OMX_VIDEO_HEVCMainTierLevel4:
4701 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
4702 break;
4703 case OMX_VIDEO_HEVCHighTierLevel4:
4704 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
4705 break;
4706 case OMX_VIDEO_HEVCMainTierLevel41:
4707 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
4708 break;
4709 case OMX_VIDEO_HEVCHighTierLevel41:
4710 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
4711 break;
4712 case OMX_VIDEO_HEVCMainTierLevel5:
4713 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
4714 break;
4715 case OMX_VIDEO_HEVCHighTierLevel5:
4716 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
4717 break;
4718 case OMX_VIDEO_HEVCMainTierLevel51:
4719 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
4720 break;
4721 case OMX_VIDEO_HEVCHighTierLevel51:
4722 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
4723 break;
4724 case OMX_VIDEO_HEVCMainTierLevel52:
4725 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
4726 break;
4727 case OMX_VIDEO_HEVCHighTierLevel52:
4728 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
4729 break;
4730 case OMX_VIDEO_HEVCMainTierLevel6:
4731 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
4732 break;
4733 case OMX_VIDEO_HEVCHighTierLevel6:
4734 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
4735 break;
4736 case OMX_VIDEO_HEVCMainTierLevel61:
4737 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
4738 break;
4739 case OMX_VIDEO_HEVCHighTierLevel61:
4740 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
4741 break;
4742 default :
4743 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
4744 requested_level.level);
4745 return false;
4746 }
4747 }
4748
4749 if (!m_profile_set) {
4750 int rc;
4751 struct v4l2_control control;
4752
4753 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4754 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
4755 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4756 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
4757 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4758 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
4759 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4760 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
4761 } else {
4762 DEBUG_PRINT_ERROR("Wrong CODEC");
4763 return false;
4764 }
4765
4766 control.value = requested_profile.profile;
4767
4768 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4769 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4770
4771 if (rc) {
4772 DEBUG_PRINT_ERROR("Failed to set control");
4773 return false;
4774 }
4775
4776 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4777
4778 codec_profile.profile = control.value;
4779 m_profile_set = true;
4780 }
4781
4782 if (!m_level_set) {
4783 int rc;
4784 struct v4l2_control control;
4785
4786 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4787 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
4788 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4789 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
4790 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4791 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
4792 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4793 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
4794 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4795 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
4796 } else {
4797 DEBUG_PRINT_ERROR("Wrong CODEC");
4798 return false;
4799 }
4800
4801 control.value = requested_level.level;
4802
4803 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4804 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4805
4806 if (rc) {
4807 DEBUG_PRINT_ERROR("Failed to set control");
4808 return false;
4809 }
4810
4811 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4812
4813 profile_level.level = control.value;
4814 m_level_set = true;
4815 }
4816
4817 return true;
4818 }
4819
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)4820 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
4821 {
4822
4823 struct venc_voptimingcfg vop_timing_cfg;
4824
4825 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
4826 (unsigned int)TimeIncRes);
4827
4828 vop_timing_cfg.voptime_resolution = TimeIncRes;
4829
4830 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
4831 return true;
4832 }
4833
venc_set_intra_period_config(OMX_U32 nPFrames,OMX_U32 nBFrames)4834 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
4835 #if _ANDROID_
4836 // Android defines nBFrames as number of Bs between I OR P
4837 // Per the spec, nBFrames is number of Bs between I
4838 OMX_U32 nBs = nBFrames * (nPFrames + 1);
4839 DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
4840 nBFrames = nBs;
4841 #endif //_ANDROID_
4842 return venc_set_intra_period(nPFrames, nBFrames);
4843 }
4844
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)4845 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
4846 {
4847
4848 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
4849 int rc;
4850 struct v4l2_control control;
4851 int pframe = 0, bframe = 0;
4852
4853 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
4854 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
4855 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
4856 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
4857 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4858 nBFrames=0;
4859 }
4860
4861 if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
4862 DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
4863 return false;
4864 }
4865
4866 intra_period.num_pframes = nPFrames;
4867 intra_period.num_bframes = nBFrames;
4868
4869 if (!venc_calibrate_gop() && !is_thulium_v1)
4870 {
4871 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4872 return false;
4873 }
4874
4875 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4876 control.value = intra_period.num_pframes;
4877 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4878
4879 if (rc) {
4880 DEBUG_PRINT_ERROR("Failed to set control");
4881 return false;
4882 }
4883
4884 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4885
4886 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4887 control.value = intra_period.num_bframes;
4888 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4889 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4890
4891 if (rc) {
4892 DEBUG_PRINT_ERROR("Failed to set control");
4893 return false;
4894 }
4895
4896 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
4897
4898 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
4899 m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4900 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4901 control.value = 1;
4902
4903 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4904
4905 if (rc) {
4906 DEBUG_PRINT_ERROR("Failed to set control");
4907 return false;
4908 }
4909 idrperiod.idrperiod = 1;
4910 }
4911 return true;
4912 }
4913
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)4914 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
4915 {
4916 int rc = 0;
4917 struct v4l2_control control;
4918 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
4919 (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
4920
4921 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
4922 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
4923 return false;
4924 }
4925
4926 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
4927 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4928 return false;
4929 }
4930
4931 if (!intra_period.num_bframes)
4932 intra_period.num_pframes = nPFrames;
4933 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4934 control.value = nIDRPeriod;
4935
4936 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4937
4938 if (rc) {
4939 DEBUG_PRINT_ERROR("Failed to set control");
4940 return false;
4941 }
4942
4943 idrperiod.idrperiod = nIDRPeriod;
4944 return true;
4945 }
4946
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)4947 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
4948 {
4949 int rc = 0;
4950 struct v4l2_control control;
4951
4952 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
4953
4954 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
4955 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
4956
4957 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
4958 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4959
4960 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4961 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4962
4963 if (rc) {
4964 DEBUG_PRINT_ERROR("Failed to set control");
4965 return false;
4966 }
4967
4968 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4969 entropy.longentropysel = control.value;
4970
4971 if (i_cabac_level == 0) {
4972 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
4973 } else if (i_cabac_level == 1) {
4974 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
4975 } else if (i_cabac_level == 2) {
4976 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
4977 }
4978
4979 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
4980 //control.value = entropy_cfg.cabacmodel;
4981 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4982 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4983
4984 if (rc) {
4985 DEBUG_PRINT_ERROR("Failed to set control");
4986 return false;
4987 }
4988
4989 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4990 entropy.cabacmodel=control.value;
4991 } else if (!enable) {
4992 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
4993 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4994 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4995 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4996
4997 if (rc) {
4998 DEBUG_PRINT_ERROR("Failed to set control");
4999 return false;
5000 }
5001
5002 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5003 entropy.longentropysel=control.value;
5004 } else {
5005 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
5006 return false;
5007 }
5008
5009 return true;
5010 }
5011
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)5012 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
5013 {
5014 int rc;
5015 struct v4l2_control control;
5016 bool status = true;
5017
5018 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) {
5019 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
5020 } else {
5021 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5022 }
5023
5024 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5025 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5026 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5027
5028 if (rc) {
5029 DEBUG_PRINT_ERROR("Failed to set control");
5030 return false;
5031 }
5032
5033 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5034 multislice.mslice_mode=control.value;
5035
5036 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
5037
5038 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
5039 control.value = nSlicesize;
5040 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
5041 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5042
5043 if (rc) {
5044 DEBUG_PRINT_ERROR("Failed to set control");
5045 return false;
5046 }
5047
5048 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5049 multislice.mslice_size=control.value;
5050
5051 }
5052
5053 return status;
5054 }
5055
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)5056 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
5057 {
5058 bool status = true;
5059 int rc;
5060 struct v4l2_control control_mode,control_mbs;
5061 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
5062
5063 // There is no disabled mode. Disabled mode is indicated by a 0 count.
5064 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
5065 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
5066 return status;
5067 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
5068 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5069 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
5070 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
5071 control_mbs.value=irMBs;
5072 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
5073 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5074 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
5075 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5076 control_mbs.value=irMBs;
5077 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
5078 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5079 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
5080 } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
5081 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5082 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
5083 control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5084 control_mbs.value = irMBs;
5085 } else {
5086 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
5087 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
5088 return false;
5089 }
5090
5091 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
5092 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
5093
5094 if (rc) {
5095 DEBUG_PRINT_ERROR("Failed to set control");
5096 return false;
5097 }
5098
5099 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
5100
5101 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
5102 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
5103
5104 if (rc) {
5105 DEBUG_PRINT_ERROR("Failed to set control");
5106 return false;
5107 }
5108
5109 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
5110
5111 intra_refresh.irmode = control_mode.value;
5112 intra_refresh.mbcount = control_mbs.value;
5113
5114 return status;
5115 }
5116
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)5117 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
5118 {
5119 bool status = true;
5120 struct venc_headerextension hec_cfg;
5121 struct venc_multiclicecfg multislice_cfg;
5122 int rc;
5123 OMX_U32 resynchMarkerSpacingBytes = 0;
5124 struct v4l2_control control;
5125
5126 memset(&control, 0, sizeof(control));
5127
5128 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5129 if (error_resilience->bEnableHEC) {
5130 hec_cfg.header_extension = 1;
5131 } else {
5132 hec_cfg.header_extension = 0;
5133 }
5134
5135 hec.header_extension = error_resilience->bEnableHEC;
5136 }
5137
5138 if (error_resilience->bEnableRVLC) {
5139 DEBUG_PRINT_ERROR("RVLC is not Supported");
5140 return false;
5141 }
5142
5143 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5144 (error_resilience->bEnableDataPartitioning)) {
5145 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
5146 return false;
5147 }
5148
5149 if (error_resilience->nResynchMarkerSpacing) {
5150 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
5151 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
5152 }
5153 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5154 (error_resilience->nResynchMarkerSpacing)) {
5155 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
5156 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5157 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5158 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
5159 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
5160 error_resilience->bEnableDataPartitioning) {
5161 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
5162 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5163 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5164 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
5165 } else {
5166 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
5167 multislice_cfg.mslice_size = 0;
5168 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5169 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5170 }
5171
5172 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
5173 multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
5174 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5175 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5176
5177 if (rc) {
5178 DEBUG_PRINT_ERROR("Failed to set Slice mode control");
5179 return false;
5180 }
5181
5182 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5183 multislice.mslice_mode=control.value;
5184
5185 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
5186 control.value = resynchMarkerSpacingBytes;
5187 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5188
5189 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5190
5191 if (rc) {
5192 DEBUG_PRINT_ERROR("Failed to set MAX MB control");
5193 return false;
5194 }
5195
5196 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5197 multislice.mslice_mode = multislice_cfg.mslice_mode;
5198 multislice.mslice_size = multislice_cfg.mslice_size;
5199 return status;
5200 }
5201
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)5202 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
5203 {
5204 int rc;
5205 struct v4l2_control control;
5206 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
5207
5208 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
5209 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
5210 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
5211 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
5212 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
5213 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
5214 }
5215
5216 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5217 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5218
5219 if (rc) {
5220 return false;
5221 }
5222
5223 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5224
5225 dbkfilter.db_mode=control.value;
5226
5227 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
5228 control.value=0;
5229
5230 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5231 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5232
5233 if (rc) {
5234 return false;
5235 }
5236
5237 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5238 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
5239 control.value=0;
5240 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5241 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5242
5243 if (rc) {
5244 return false;
5245 }
5246
5247 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5248
5249
5250 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
5251 return true;
5252 }
5253
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)5254 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
5255 {
5256 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
5257 (unsigned int)nTargetBitrate);
5258 struct v4l2_control control;
5259 int rc = 0;
5260 control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
5261 control.value = nTargetBitrate;
5262
5263 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5264 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5265
5266 if (rc) {
5267 DEBUG_PRINT_ERROR("Failed to set control");
5268 return false;
5269 }
5270
5271 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5272
5273
5274 m_sVenc_cfg.targetbitrate = control.value;
5275 bitrate.target_bitrate = control.value;
5276
5277 if (!config) {
5278 m_level_set = false;
5279
5280 if (venc_set_profile_level(0, 0)) {
5281 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
5282 }
5283 }
5284
5285 // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
5286 // has been specified
5287 if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
5288 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
5289 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5290
5291 DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
5292 for (OMX_U32 i = 0; i < numLayers; ++i) {
5293 layerBitrates[i] =
5294 (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
5295 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
5296 i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
5297 layerBitrates[i], bitrate.target_bitrate);
5298 }
5299 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
5300 return false;
5301 }
5302 }
5303
5304 return true;
5305 }
5306
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)5307 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
5308 {
5309 struct v4l2_streamparm parm;
5310 int rc = 0;
5311 struct venc_framerate frame_rate_cfg;
5312 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
5313 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5314 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
5315 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
5316
5317 if (frame_rate_cfg.fps_numerator > 0)
5318 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
5319
5320 if (rc) {
5321 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
5322 return false;
5323 }
5324
5325 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
5326 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
5327
5328 if (!config) {
5329 m_level_set = false;
5330
5331 if (venc_set_profile_level(0, 0)) {
5332 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
5333 }
5334 }
5335
5336 return true;
5337 }
5338
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)5339 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
5340 {
5341 struct v4l2_format fmt;
5342 int color_space = 0;
5343 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
5344
5345 switch ((int)color_format) {
5346 case OMX_COLOR_FormatYUV420SemiPlanar:
5347 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
5348 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
5349 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5350 break;
5351 case QOMX_COLOR_FormatYVU420SemiPlanar:
5352 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
5353 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5354 break;
5355 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
5356 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
5357 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5358 break;
5359 case QOMX_COLOR_Format32bitRGBA8888:
5360 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
5361 break;
5362 case QOMX_COLOR_Format32bitRGBA8888Compressed:
5363 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
5364 break;
5365 default:
5366 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
5367 m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
5368 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5369 DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
5370 break;
5371 }
5372
5373 memset(&fmt, 0, sizeof(fmt));
5374 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5375 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
5376 fmt.fmt.pix_mp.colorspace = color_space;
5377 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
5378 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
5379
5380 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5381 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
5382 return false;
5383 }
5384
5385 return true;
5386 }
5387
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)5388 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
5389 {
5390 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
5391
5392 if (intra_vop_refresh == OMX_TRUE) {
5393 struct v4l2_control control;
5394 int rc;
5395 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
5396 control.value = 1;
5397 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5398 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5399
5400 if (rc) {
5401 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
5402 return false;
5403 }
5404
5405 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5406 } else {
5407 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
5408 }
5409
5410 return true;
5411 }
5412
venc_set_deinterlace(OMX_U32 enable)5413 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
5414 {
5415 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
5416 struct v4l2_control control;
5417 int rc;
5418 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
5419 if (enable)
5420 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5421 else
5422 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5423
5424 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5425 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5426 if (rc) {
5427 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
5428 return false;
5429 }
5430 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5431 deinterlace_enabled = true;
5432 return true;
5433 }
5434
venc_calibrate_gop()5435 bool venc_dev::venc_calibrate_gop()
5436 {
5437 int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
5438 int num_sub_gops_in_a_gop;
5439 nPframes = intra_period.num_pframes;
5440 nBframes = intra_period.num_bframes;
5441 nLayers = hier_layers.numlayers;
5442 if (temporal_layers_config.nPLayers) {
5443 nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5444 }
5445
5446 if (!nPframes && nLayers) {
5447 DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
5448 return false;
5449 }
5450
5451 if (nLayers > 1) { /*Multi-layer encoding*/
5452 sub_gop_size = 1 << (nLayers - 1);
5453 /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
5454 * below calculations we are ignoring +1 . Ignoring +1 in below
5455 * calculations is not a mistake but intentional.
5456 */
5457 gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
5458 num_sub_gops_in_a_gop = gop_size/sub_gop_size;
5459 if (nBframes) { /*Hier-B case*/
5460 /*
5461 * Frame Type--> I B B B P B B B P I B B P ...
5462 * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ...
5463 * nPframes = 2, nBframes = 6, nLayers = 3
5464 *
5465 * Intention is to keep the intraperiod as close as possible to what is desired
5466 * by the client while adjusting nPframes and nBframes to meet other constraints.
5467 * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2
5468 * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
5469 *
5470 * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
5471 * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
5472 */
5473 nPframes = num_sub_gops_in_a_gop;
5474 nBframes = gop_size - nPframes;
5475 } else { /*Hier-P case*/
5476 /*
5477 * Frame Type--> I P P P P P P P I P P P P ...
5478 * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ...
5479 * nPframes = 7, nBframes = 0, nLayers = 3
5480 *
5481 * Intention is to keep the intraperiod as close as possible to what is desired
5482 * by the client while adjusting nPframes and nBframes to meet other constraints.
5483 * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
5484 * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
5485 *
5486 * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
5487 * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
5488 */
5489 nPframes = gop_size - 1;
5490 }
5491 } else { /*Single-layer encoding*/
5492 if (nBframes) {
5493 /* I P B B B P B B B P B B B I P B B...
5494 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...
5495 * nPframes = 3, nBframes = 9, nLayers = 0
5496 *
5497 * ratio is rounded,
5498 * eg1: nPframes = 9, nBframes = 11 => ratio = 1
5499 * eg2: nPframes = 9, nBframes = 16 => ratio = 2
5500 */
5501 ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
5502 nBframes = ratio * nPframes;
5503 }
5504 }
5505 DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
5506 intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
5507 intra_period.num_pframes = nPframes;
5508 intra_period.num_bframes = nBframes;
5509 hier_layers.numlayers = nLayers;
5510 return true;
5511 }
5512
venc_set_bitrate_type(OMX_U32 type)5513 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
5514 {
5515 struct v4l2_control control;
5516 int rc = 0;
5517 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
5518 control.value = type;
5519 DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
5520 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5521 if (rc) {
5522 DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
5523 bitrate_type_string(type));
5524 return false;
5525 }
5526 return true;
5527 }
5528
venc_set_layer_bitrates(OMX_U32 * layerBitrate,OMX_U32 numLayers)5529 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
5530 {
5531 DEBUG_PRINT_LOW("venc_set_layer_bitrates");
5532 struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
5533 struct v4l2_ext_controls controls;
5534 int rc = 0;
5535 OMX_U32 i;
5536
5537 if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
5538 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
5539 return false;
5540 }
5541
5542 for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
5543 if (!layerBitrate[i]) {
5544 DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
5545 return false;
5546 } else {
5547 ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
5548 ctrl[i].value = layerBitrate[i];
5549 }
5550 }
5551 controls.count = numLayers;
5552 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5553 controls.controls = ctrl;
5554
5555 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5556 if (rc) {
5557 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
5558 return false;
5559 }
5560
5561 DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
5562 return true;
5563 }
5564
venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE * hhp)5565 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
5566 {
5567 DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
5568 struct v4l2_control control;
5569 int rc;
5570
5571 if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
5572 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5573 return false;
5574 }
5575
5576 if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
5577 DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
5578 return false;
5579 }
5580 if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
5581 DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
5582 return false;
5583 }
5584
5585 hier_layers.numlayers = hhp->nHpLayers;
5586 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5587 hier_layers.hier_mode = HIER_P_HYBRID;
5588 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5589 hier_layers.hier_mode = HIER_P;
5590 }
5591 if (venc_calibrate_gop()) {
5592 // Update the driver with the new nPframes and nBframes
5593 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
5594 control.value = intra_period.num_pframes;
5595 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5596 if (rc) {
5597 DEBUG_PRINT_ERROR("Failed to set control");
5598 return false;
5599 }
5600
5601 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
5602 control.value = intra_period.num_bframes;
5603 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5604 if (rc) {
5605 DEBUG_PRINT_ERROR("Failed to set control");
5606 return false;
5607 }
5608 DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
5609 intra_period.num_pframes, intra_period.num_bframes);
5610 } else {
5611 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5612 return false;
5613 }
5614 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5615 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
5616 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5617 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
5618 }
5619 control.value = hhp->nHpLayers - 1;
5620
5621 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
5622 control.id, control.value);
5623
5624 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5625 if (rc) {
5626 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
5627 return false;
5628 }
5629
5630 DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
5631 control.id, control.value);
5632 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5633 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
5634 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
5635 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5636 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5637 return false;
5638 }
5639 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5640 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
5641 control.value = hhp->nHpLayers - 1;
5642 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5643 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5644 return false;
5645 }
5646 } else {
5647 DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
5648 return false;
5649 }
5650
5651 if(venc_set_session_qp_range (hhp->nMinQuantizer,
5652 hhp->nMaxQuantizer) == false) {
5653 DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
5654 (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
5655 return false;
5656 } else {
5657 session_qp_values.minqp = hhp->nMinQuantizer;
5658 session_qp_values.maxqp = hhp->nMaxQuantizer;
5659 }
5660
5661 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
5662 for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
5663 layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
5664 hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
5665 DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
5666 }
5667 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
5668 DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
5669 hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
5670 hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
5671 hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
5672 return false;
5673 }
5674 hybrid_hp.nHpLayers = hhp->nHpLayers;
5675
5676 // Set this or else the layer0 bitrate will be overwritten by
5677 // default value in component
5678 m_sVenc_cfg.targetbitrate = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
5679 hybrid_hp.nHpLayers = hhp->nHpLayers;
5680 hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
5681 hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
5682 hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
5683 return true;
5684 }
5685
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)5686 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
5687 {
5688 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
5689 struct v4l2_ext_control ctrl[2];
5690 struct v4l2_ext_controls controls;
5691 int rc;
5692
5693 if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
5694 DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
5695 return false;
5696 }
5697
5698 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
5699 if (enable)
5700 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
5701 else
5702 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
5703
5704 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
5705 if (enable && count > 0)
5706 ctrl[1].value = count;
5707 else if (enable)
5708 ctrl[1].value = 1;
5709 else
5710 ctrl[1].value = 0;
5711
5712 controls.count = 2;
5713 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5714 controls.controls = ctrl;
5715
5716 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
5717 controls.controls[0].id, controls.controls[0].value,
5718 controls.controls[1].id, controls.controls[1].value);
5719
5720 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5721 if (rc) {
5722 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5723 return false;
5724 }
5725 ltrinfo.enabled = enable;
5726 ltrinfo.count = count;
5727
5728 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
5729 controls.controls[0].id, controls.controls[0].value,
5730 controls.controls[1].id, controls.controls[1].value);
5731
5732 if (!venc_set_profile_level(0, 0)) {
5733 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
5734 __func__);
5735 } else {
5736 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
5737 __func__, codec_profile.profile, profile_level.level);
5738 }
5739
5740 return true;
5741 }
5742
venc_set_useltr(OMX_U32 frameIdx)5743 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
5744 {
5745 DEBUG_PRINT_LOW("venc_use_goldenframe");
5746 int rc = true;
5747 struct v4l2_control control;
5748
5749 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
5750 control.value = frameIdx;
5751
5752 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5753 if (rc) {
5754 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
5755 return false;
5756 }
5757
5758 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5759 control.id, control.value);
5760 return true;
5761 }
5762
venc_set_markltr(OMX_U32 frameIdx)5763 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
5764 {
5765 DEBUG_PRINT_LOW("venc_set_goldenframe");
5766 int rc = true;
5767 struct v4l2_control control;
5768
5769 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
5770 control.value = frameIdx;
5771
5772 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5773 if (rc) {
5774 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5775 return false;
5776 }
5777
5778 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5779 control.id, control.value);
5780 return true;
5781 }
5782
venc_set_vpe_rotation(OMX_S32 rotation_angle)5783 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
5784 {
5785 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
5786 struct v4l2_control control;
5787 int rc;
5788 struct v4l2_format fmt;
5789 struct v4l2_requestbuffers bufreq;
5790
5791 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
5792 if (rotation_angle == 0)
5793 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
5794 else if (rotation_angle == 90)
5795 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
5796 else if (rotation_angle == 180)
5797 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
5798 else if (rotation_angle == 270)
5799 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
5800 else {
5801 DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
5802 return false;
5803 }
5804
5805 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5806 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5807 if (rc) {
5808 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
5809 return false;
5810 }
5811 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5812
5813 memset(&fmt, 0, sizeof(fmt));
5814 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5815 if (rotation_angle == 90 || rotation_angle == 270) {
5816 OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
5817 OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
5818 m_sVenc_cfg.dvs_height = nHeight;
5819 m_sVenc_cfg.dvs_width = nWidth;
5820 DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
5821 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
5822 }
5823
5824 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
5825 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
5826 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
5827 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5828 DEBUG_PRINT_ERROR("Failed to set format on capture port");
5829 return false;
5830 }
5831
5832 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
5833 bufreq.memory = V4L2_MEMORY_USERPTR;
5834 bufreq.count = m_sOutput_buff_property.actualcount;
5835 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5836 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
5837 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
5838 return false;
5839 }
5840 if (bufreq.count >= m_sOutput_buff_property.mincount)
5841 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
5842
5843 return true;
5844 }
5845
venc_set_searchrange()5846 bool venc_dev::venc_set_searchrange()
5847 {
5848 DEBUG_PRINT_LOW("venc_set_searchrange");
5849 struct v4l2_control control;
5850 struct v4l2_ext_control ctrl[6];
5851 struct v4l2_ext_controls controls;
5852 int rc;
5853
5854 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5855 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5856 ctrl[0].value = 16;
5857 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5858 ctrl[1].value = 4;
5859 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5860 ctrl[2].value = 16;
5861 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5862 ctrl[3].value = 4;
5863 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5864 ctrl[4].value = 12;
5865 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5866 ctrl[5].value = 4;
5867 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
5868 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
5869 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5870 ctrl[0].value = 16;
5871 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5872 ctrl[1].value = 4;
5873 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5874 ctrl[2].value = 16;
5875 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5876 ctrl[3].value = 4;
5877 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5878 ctrl[4].value = 12;
5879 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5880 ctrl[5].value = 4;
5881 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5882 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5883 ctrl[0].value = 4;
5884 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5885 ctrl[1].value = 4;
5886 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5887 ctrl[2].value = 4;
5888 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5889 ctrl[3].value = 4;
5890 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5891 ctrl[4].value = 4;
5892 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5893 ctrl[5].value = 4;
5894 } else {
5895 DEBUG_PRINT_ERROR("Invalid codec type");
5896 return false;
5897 }
5898 controls.count = 6;
5899 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5900 controls.controls = ctrl;
5901
5902 DEBUG_PRINT_LOW(" Calling IOCTL set control for"
5903 "id=%x, val=%d id=%x, val=%d"
5904 "id=%x, val=%d id=%x, val=%d"
5905 "id=%x, val=%d id=%x, val=%d",
5906 controls.controls[0].id, controls.controls[0].value,
5907 controls.controls[1].id, controls.controls[1].value,
5908 controls.controls[2].id, controls.controls[2].value,
5909 controls.controls[3].id, controls.controls[3].value,
5910 controls.controls[4].id, controls.controls[4].value,
5911 controls.controls[5].id, controls.controls[5].value);
5912
5913 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5914 if (rc) {
5915 DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
5916 return false;
5917 }
5918 return true;
5919 }
5920
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)5921 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
5922 {
5923 bool status = true;
5924 struct v4l2_control control;
5925 int rc = 0;
5926 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
5927
5928 switch (eControlRate) {
5929 case OMX_Video_ControlRateDisable:
5930 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
5931 break;
5932 case OMX_Video_ControlRateVariableSkipFrames:
5933 (supported_rc_modes & RC_VBR_VFR) ?
5934 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
5935 status = false;
5936 break;
5937 case OMX_Video_ControlRateVariable:
5938 (supported_rc_modes & RC_VBR_CFR) ?
5939 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
5940 status = false;
5941 break;
5942 case OMX_Video_ControlRateConstantSkipFrames:
5943 (supported_rc_modes & RC_CBR_VFR) ?
5944 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
5945 status = false;
5946 break;
5947 case OMX_Video_ControlRateConstant:
5948 (supported_rc_modes & RC_CBR_CFR) ?
5949 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
5950 status = false;
5951 break;
5952 default:
5953 status = false;
5954 break;
5955 }
5956
5957 if (status) {
5958
5959 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5960 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5961
5962 if (rc) {
5963 DEBUG_PRINT_ERROR("Failed to set control");
5964 return false;
5965 }
5966
5967 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5968
5969 rate_ctrl.rcmode = control.value;
5970 }
5971
5972 #ifdef _VQZIP_
5973 if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
5974 && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5975 /* Enable VQZIP SEI by default for camcorder RC modes */
5976
5977 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
5978 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
5979 DEBUG_PRINT_HIGH("Set VQZIP SEI:");
5980 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
5981 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
5982 }
5983 }
5984 #endif //_VQZIP_
5985
5986 return status;
5987 }
5988
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)5989 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
5990 {
5991 bool status = true;
5992 struct v4l2_control control;
5993 int rc = 0;
5994 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
5995
5996 switch (ePerfLevel) {
5997 case OMX_QCOM_PerfLevelNominal:
5998 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
5999 break;
6000 case OMX_QCOM_PerfLevelTurbo:
6001 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
6002 break;
6003 default:
6004 status = false;
6005 break;
6006 }
6007
6008 if (status) {
6009 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6010 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6011
6012 if (rc) {
6013 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
6014 return false;
6015 }
6016
6017 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6018 }
6019 return status;
6020 }
6021
venc_set_perf_mode(OMX_U32 mode)6022 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
6023 {
6024 struct v4l2_control control;
6025 if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
6026 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
6027 control.value = mode;
6028 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6029 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6030 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6031 return false;
6032 }
6033 return true;
6034 } else {
6035 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
6036 return false;
6037 }
6038 }
6039
venc_set_qp(OMX_U32 nQp)6040 bool venc_dev::venc_set_qp(OMX_U32 nQp)
6041 {
6042 struct v4l2_control control;
6043 if (nQp) {
6044 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
6045 control.value = nQp;
6046 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6047 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6048 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6049 return false;
6050 }
6051 } else {
6052 DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
6053 return false;
6054 }
6055 return true;
6056 }
6057
venc_set_aspectratio(void * nSar)6058 bool venc_dev::venc_set_aspectratio(void *nSar)
6059 {
6060 int rc;
6061 struct v4l2_control control;
6062 struct v4l2_ext_control ctrl[2];
6063 struct v4l2_ext_controls controls;
6064 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
6065
6066 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
6067
6068 ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
6069 ctrl[0].value = sar->nSARWidth;
6070 ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
6071 ctrl[1].value = sar->nSARHeight;
6072
6073 controls.count = 2;
6074 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
6075 controls.controls = ctrl;
6076
6077 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
6078 controls.controls[0].id, controls.controls[0].value,
6079 controls.controls[1].id, controls.controls[1].value);
6080
6081 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
6082 if (rc) {
6083 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
6084 return false;
6085 }
6086
6087 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
6088 controls.controls[0].id, controls.controls[0].value,
6089 controls.controls[1].id, controls.controls[1].value);
6090 return true;
6091 }
6092
venc_set_hierp_layers(OMX_U32 hierp_layers)6093 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
6094 {
6095 struct v4l2_control control;
6096 if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
6097 (hierp_layers <= hier_layers.numlayers)) {
6098 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6099 control.value = hierp_layers - 1;
6100 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
6101 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6102 DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
6103 return false;
6104 }
6105 return true;
6106 } else {
6107 DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
6108 hierp_layers);
6109 return false;
6110 }
6111 }
6112
venc_set_baselayerid(OMX_U32 baseid)6113 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
6114 {
6115 struct v4l2_control control;
6116 if (hier_layers.hier_mode == HIER_P) {
6117 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
6118 control.value = baseid;
6119 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6120 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6121 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6122 return false;
6123 }
6124 return true;
6125 } else {
6126 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
6127 hier_layers.hier_mode);
6128 return false;
6129 }
6130 }
6131
venc_set_vui_timing_info(OMX_BOOL enable)6132 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
6133 {
6134 struct v4l2_control control;
6135 int rc = 0;
6136 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
6137
6138 if (enable)
6139 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
6140 else
6141 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
6142
6143 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
6144 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6145 if (rc) {
6146 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
6147 return false;
6148 }
6149 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
6150 return true;
6151 }
6152
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)6153 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
6154 {
6155 struct v4l2_control control;
6156 int rc = 0;
6157 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
6158 control.value = nPeakBitrate;
6159
6160 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
6161
6162 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6163 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6164
6165 if (rc) {
6166 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
6167 return false;
6168 }
6169
6170 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6171
6172 return true;
6173 }
6174
venc_set_vpx_error_resilience(OMX_BOOL enable)6175 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
6176 {
6177 struct v4l2_control control;
6178 int rc = 0;
6179 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
6180
6181 if (enable)
6182 control.value = 1;
6183 else
6184 control.value = 0;
6185
6186 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
6187
6188 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6189
6190 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6191 if (rc) {
6192 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
6193 return false;
6194 }
6195 vpx_err_resilience.enable = 1;
6196 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6197 return true;
6198 }
6199
venc_set_priority(OMX_U32 priority)6200 bool venc_dev::venc_set_priority(OMX_U32 priority) {
6201 struct v4l2_control control;
6202
6203 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
6204 if (priority == 0)
6205 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
6206 else
6207 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
6208
6209 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6210 DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
6211 priority == 0 ? "ENABLE" : "DISABLE");
6212 return false;
6213 }
6214 return true;
6215 }
6216
venc_set_operatingrate(OMX_U32 rate)6217 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
6218 struct v4l2_control control;
6219
6220 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
6221 control.value = rate;
6222
6223 DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
6224 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6225
6226 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6227 hw_overload = errno == EBUSY;
6228 DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
6229 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
6230 return false;
6231 }
6232 operating_rate = rate;
6233 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16);
6234 return true;
6235 }
6236
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)6237 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
6238 char *userptr;
6239 int fd;
6240 unsigned offset;
6241 ssize_t size;
6242 struct msm_vidc_roi_qp_payload *roiData;
6243 if (!roiInfo) {
6244 DEBUG_PRINT_ERROR("No ROI info present");
6245 return false;
6246 }
6247 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
6248 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
6249 DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
6250 return false;
6251 }
6252
6253 venc_roiqp_log_buffers(roiInfo);
6254 mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
6255 if (!userptr || size < roiInfo->nRoiMBInfoSize) {
6256 DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
6257 return false;
6258 }
6259
6260 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
6261 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
6262 data->nVersion.nVersion = OMX_SPEC_VERSION;
6263 data->nPortIndex = 0;
6264 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
6265 data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
6266
6267 roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
6268 roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
6269 roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
6270 roiData->b_roi_info = roiInfo->bUseRoiInfo;
6271 roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
6272 memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
6273
6274 data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
6275 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
6276 data->nVersion.nVersion = OMX_SPEC_VERSION;
6277 data->nPortIndex = 0;
6278 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
6279 data->nDataSize = 0;
6280 return true;
6281 }
6282
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)6283 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
6284 OMX_U32 *nMaxBLayers) {
6285
6286 // no B-layers for all cases
6287 temporal_layers_config.nMaxBLayers = 0;
6288 temporal_layers_config.nMaxLayers = 1;
6289
6290 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6291 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6292 temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
6293 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6294 temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
6295 }
6296
6297 *nMaxLayers = temporal_layers_config.nMaxLayers;
6298 *nMaxBLayers = temporal_layers_config.nMaxBLayers;
6299 return true;
6300 }
6301
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)6302 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
6303 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
6304
6305 if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6306 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
6307 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
6308 DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
6309 return OMX_ErrorUnsupportedSetting;
6310 }
6311
6312 if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
6313 (pTemporalParams->nBLayerCountActual != 0 ||
6314 pTemporalParams->nPLayerCountActual != 1)) {
6315 return OMX_ErrorBadParameter;
6316 } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
6317 pTemporalParams->nPLayerCountActual < 1) {
6318 return OMX_ErrorBadParameter;
6319 }
6320
6321 if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
6322 DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
6323 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
6324 return OMX_ErrorBadParameter;
6325 } else if (pTemporalParams->nPLayerCountActual >
6326 temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
6327 DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
6328 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
6329 temporal_layers_config.nMaxLayers);
6330 return OMX_ErrorBadParameter;
6331 }
6332
6333 // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
6334 // use hybrid-HP for best results
6335 bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
6336 bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
6337 bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
6338
6339 // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
6340 bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
6341
6342 DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
6343 rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
6344
6345 if (bUseHybridMode &&
6346 !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
6347 pTemporalParams->nBLayerCountActual,
6348 0 /* LTR count */, (int) HIER_P_HYBRID)) {
6349 bUseHybridMode = false;
6350 DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
6351 }
6352
6353 if (intra_period.num_bframes) {
6354 DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
6355 return OMX_ErrorUnsupportedSetting;
6356 }
6357
6358 if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
6359 DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
6360 intra_period.num_pframes, intra_period.num_bframes);
6361 return OMX_ErrorUnsupportedSetting;
6362 }
6363
6364 struct v4l2_control control;
6365 // Num enhancements layers does not include the base-layer
6366 control.value = pTemporalParams->nPLayerCountActual - 1;
6367
6368 if (bUseHybridMode) {
6369 DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
6370 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6371 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6372 bUseHybridMode = false;
6373 DEBUG_PRINT_ERROR("Failed to set hybrid HP");
6374 } else {
6375 // Disable normal HP if Hybrid mode is being enabled
6376 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6377 control.value = 0;
6378 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6379 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6380 return OMX_ErrorUnsupportedSetting;
6381 }
6382 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6383 control.value = 0;
6384 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6385 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
6386 return OMX_ErrorUnsupportedSetting;
6387 }
6388 }
6389 }
6390
6391 if (!bUseHybridMode) {
6392
6393 // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
6394 if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
6395 DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
6396 return OMX_ErrorUnsupportedSetting;
6397 }
6398
6399 DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
6400 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6401 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6402 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
6403 return OMX_ErrorUnsupportedSetting;
6404 }
6405
6406 // configure max layers for a session.. Okay to use current num-layers as max
6407 // since we do not plan to support dynamic changes to number of layers
6408 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6409 control.value = pTemporalParams->nPLayerCountActual - 1;
6410 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6411 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6412 return OMX_ErrorUnsupportedSetting;
6413
6414 } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
6415 // Disable hybrid mode if it was enabled already
6416 DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
6417 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6418 control.value = 0;
6419 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6420 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
6421 return OMX_ErrorUnsupportedSetting;
6422 }
6423 }
6424 }
6425
6426 // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
6427 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6428 DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
6429 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
6430 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
6431 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6432 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
6433 return OMX_ErrorUnsupportedSetting;
6434 }
6435 }
6436
6437 temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
6438 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
6439 temporal_layers_config.nBLayers = 0;
6440
6441 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
6442 if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
6443 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
6444 return OMX_ErrorNone;
6445 }
6446 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
6447
6448 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
6449 numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
6450
6451 OMX_U32 i = 0;
6452 for (; i < numLayers; ++i) {
6453 OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
6454 OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
6455 if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
6456 DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
6457 return OMX_ErrorBadParameter;
6458 } else {
6459 layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
6460 temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
6461 temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
6462 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
6463 i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
6464 }
6465 }
6466
6467 temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
6468
6469 // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
6470 if (bitrate.target_bitrate > 0) {
6471 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
6472 return OMX_ErrorUnsupportedSetting;
6473 }
6474 } else {
6475 DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
6476 }
6477
6478 return OMX_ErrorNone;
6479 }
6480
venc_set_temporal_layers_internal()6481 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
6482 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
6483 memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
6484
6485 if (!temporal_layers_config.nPLayers) {
6486 return OMX_ErrorNone;
6487 }
6488 pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6489 pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
6490 pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
6491 pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6492 pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
6493 pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
6494 pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
6495 if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
6496 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
6497 pTemporalParams.nBitrateRatios[i] =
6498 temporal_layers_config.nTemporalLayerBitrateRatio[i];
6499 }
6500 }
6501 return venc_set_temporal_layers(&pTemporalParams);
6502 }
6503
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6504 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
6505 {
6506 bool status = true;
6507
6508 if (eProfile == NULL || eLevel == NULL) {
6509 return false;
6510 }
6511
6512 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6513 switch (codec_profile.profile) {
6514 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6515 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6516 break;
6517 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6518 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6519 break;
6520 default:
6521 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
6522 status = false;
6523 break;
6524 }
6525
6526 if (!status) {
6527 return status;
6528 }
6529
6530 //profile level
6531 switch (profile_level.level) {
6532 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
6533 *eLevel = OMX_VIDEO_MPEG4Level0;
6534 break;
6535 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
6536 *eLevel = OMX_VIDEO_MPEG4Level0b;
6537 break;
6538 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
6539 *eLevel = OMX_VIDEO_MPEG4Level1;
6540 break;
6541 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
6542 *eLevel = OMX_VIDEO_MPEG4Level2;
6543 break;
6544 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
6545 *eLevel = OMX_VIDEO_MPEG4Level3;
6546 break;
6547 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
6548 *eLevel = OMX_VIDEO_MPEG4Level4;
6549 break;
6550 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
6551 *eLevel = OMX_VIDEO_MPEG4Level5;
6552 break;
6553 default:
6554 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6555 status = false;
6556 break;
6557 }
6558 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6559 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
6560 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6561 } else {
6562 *eProfile = OMX_VIDEO_H263ProfileMax;
6563 return false;
6564 }
6565
6566 switch (profile_level.level) {
6567 case VEN_LEVEL_H263_10:
6568 *eLevel = OMX_VIDEO_H263Level10;
6569 break;
6570 case VEN_LEVEL_H263_20:
6571 *eLevel = OMX_VIDEO_H263Level20;
6572 break;
6573 case VEN_LEVEL_H263_30:
6574 *eLevel = OMX_VIDEO_H263Level30;
6575 break;
6576 case VEN_LEVEL_H263_40:
6577 *eLevel = OMX_VIDEO_H263Level40;
6578 break;
6579 case VEN_LEVEL_H263_45:
6580 *eLevel = OMX_VIDEO_H263Level45;
6581 break;
6582 case VEN_LEVEL_H263_50:
6583 *eLevel = OMX_VIDEO_H263Level50;
6584 break;
6585 case VEN_LEVEL_H263_60:
6586 *eLevel = OMX_VIDEO_H263Level60;
6587 break;
6588 case VEN_LEVEL_H263_70:
6589 *eLevel = OMX_VIDEO_H263Level70;
6590 break;
6591 default:
6592 *eLevel = OMX_VIDEO_H263LevelMax;
6593 status = false;
6594 break;
6595 }
6596 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6597 switch (codec_profile.profile) {
6598 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6599 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6600 break;
6601 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6602 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6603 break;
6604 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6605 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6606 break;
6607 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6608 *eProfile = OMX_VIDEO_AVCProfileMain;
6609 break;
6610 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6611 *eProfile = OMX_VIDEO_AVCProfileHigh;
6612 break;
6613 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6614 *eProfile = OMX_VIDEO_AVCProfileExtended;
6615 break;
6616 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6617 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6618 break;
6619 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6620 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6621 break;
6622 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6623 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6624 break;
6625 default:
6626 *eProfile = OMX_VIDEO_AVCProfileMax;
6627 status = false;
6628 break;
6629 }
6630
6631 if (!status) {
6632 return status;
6633 }
6634
6635 switch (profile_level.level) {
6636 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
6637 *eLevel = OMX_VIDEO_AVCLevel1;
6638 break;
6639 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
6640 *eLevel = OMX_VIDEO_AVCLevel1b;
6641 break;
6642 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
6643 *eLevel = OMX_VIDEO_AVCLevel11;
6644 break;
6645 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
6646 *eLevel = OMX_VIDEO_AVCLevel12;
6647 break;
6648 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
6649 *eLevel = OMX_VIDEO_AVCLevel13;
6650 break;
6651 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
6652 *eLevel = OMX_VIDEO_AVCLevel2;
6653 break;
6654 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
6655 *eLevel = OMX_VIDEO_AVCLevel21;
6656 break;
6657 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
6658 *eLevel = OMX_VIDEO_AVCLevel22;
6659 break;
6660 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
6661 *eLevel = OMX_VIDEO_AVCLevel3;
6662 break;
6663 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
6664 *eLevel = OMX_VIDEO_AVCLevel31;
6665 break;
6666 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
6667 *eLevel = OMX_VIDEO_AVCLevel32;
6668 break;
6669 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
6670 *eLevel = OMX_VIDEO_AVCLevel4;
6671 break;
6672 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
6673 *eLevel = OMX_VIDEO_AVCLevel41;
6674 break;
6675 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
6676 *eLevel = OMX_VIDEO_AVCLevel42;
6677 break;
6678 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
6679 *eLevel = OMX_VIDEO_AVCLevel5;
6680 break;
6681 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
6682 *eLevel = OMX_VIDEO_AVCLevel51;
6683 break;
6684 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
6685 *eLevel = OMX_VIDEO_AVCLevel52;
6686 break;
6687 default :
6688 *eLevel = OMX_VIDEO_AVCLevelMax;
6689 status = false;
6690 break;
6691 }
6692 }
6693 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6694 switch (codec_profile.profile) {
6695 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6696 *eProfile = OMX_VIDEO_VP8ProfileMain;
6697 break;
6698 default:
6699 *eProfile = OMX_VIDEO_VP8ProfileMax;
6700 status = false;
6701 break;
6702 }
6703 if (!status) {
6704 return status;
6705 }
6706
6707 switch (profile_level.level) {
6708 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6709 *eLevel = OMX_VIDEO_VP8Level_Version0;
6710 break;
6711 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6712 *eLevel = OMX_VIDEO_VP8Level_Version1;
6713 break;
6714 default:
6715 *eLevel = OMX_VIDEO_VP8LevelMax;
6716 status = false;
6717 break;
6718 }
6719 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6720 switch (codec_profile.profile) {
6721 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6722 *eProfile = OMX_VIDEO_HEVCProfileMain;
6723 break;
6724 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6725 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6726 break;
6727 default:
6728 *eProfile = OMX_VIDEO_HEVCProfileMax;
6729 status = false;
6730 break;
6731 }
6732 if (!status) {
6733 return status;
6734 }
6735
6736 switch (profile_level.level) {
6737 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
6738 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
6739 break;
6740 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
6741 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
6742 break;
6743 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
6744 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
6745 break;
6746 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
6747 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
6748 break;
6749 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
6750 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
6751 break;
6752 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
6753 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
6754 break;
6755 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
6756 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
6757 break;
6758 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
6759 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
6760 break;
6761 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
6762 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
6763 break;
6764 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
6765 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
6766 break;
6767 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
6768 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
6769 break;
6770 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
6771 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
6772 break;
6773 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
6774 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
6775 break;
6776 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
6777 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
6778 break;
6779 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
6780 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
6781 break;
6782 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
6783 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
6784 break;
6785 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
6786 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
6787 break;
6788 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
6789 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
6790 break;
6791 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
6792 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
6793 break;
6794 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
6795 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
6796 break;
6797 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
6798 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
6799 break;
6800 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
6801 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
6802 break;
6803 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
6804 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
6805 break;
6806 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
6807 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
6808 break;
6809 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
6810 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
6811 break;
6812 default:
6813 *eLevel = OMX_VIDEO_HEVCLevelMax;
6814 status = false;
6815 break;
6816 }
6817 }
6818
6819 return status;
6820 }
6821
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6822 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
6823 {
6824 OMX_U32 new_profile = 0, new_level = 0;
6825 unsigned const int *profile_tbl = NULL;
6826 OMX_U32 mb_per_frame, mb_per_sec;
6827 bool profile_level_found = false;
6828
6829 DEBUG_PRINT_LOW("Init profile table for respective codec");
6830
6831 //validate the ht,width,fps,bitrate and set the appropriate profile and level
6832 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6833 if (*eProfile == 0) {
6834 if (!m_profile_set) {
6835 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6836 } else {
6837 switch (codec_profile.profile) {
6838 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6839 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6840 break;
6841 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6842 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6843 break;
6844 default:
6845 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6846 return false;
6847 }
6848 }
6849 }
6850
6851 if (*eLevel == 0 && !m_level_set) {
6852 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6853 }
6854
6855 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
6856 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
6857 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
6858 profile_tbl = (unsigned int const *)
6859 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
6860 } else {
6861 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
6862 return false;
6863 }
6864 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6865 if (*eProfile == 0) {
6866 if (!m_profile_set) {
6867 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6868 } else {
6869 switch (codec_profile.profile) {
6870 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6871 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6872 break;
6873 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6874 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6875 break;
6876 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6877 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6878 break;
6879 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6880 *eProfile = OMX_VIDEO_AVCProfileMain;
6881 break;
6882 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6883 *eProfile = OMX_VIDEO_AVCProfileExtended;
6884 break;
6885 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6886 *eProfile = OMX_VIDEO_AVCProfileHigh;
6887 break;
6888 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6889 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6890 break;
6891 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6892 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6893 break;
6894 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6895 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6896 break;
6897 default:
6898 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6899 return false;
6900 }
6901 }
6902 }
6903
6904 if (*eLevel == 0 && !m_level_set) {
6905 *eLevel = OMX_VIDEO_AVCLevelMax;
6906 }
6907
6908 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
6909 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
6910 profile_tbl = (unsigned int const *)h264_profile_level_table;
6911 } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
6912 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
6913 profile_tbl = (unsigned int const *)
6914 (&h264_profile_level_table[H264_HP_START]);
6915 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
6916 profile_tbl = (unsigned int const *)
6917 (&h264_profile_level_table[H264_MP_START]);
6918 } else {
6919 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
6920 return false;
6921 }
6922 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6923 if (*eProfile == 0) {
6924 if (!m_profile_set) {
6925 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6926 } else {
6927 switch (codec_profile.profile) {
6928 case VEN_PROFILE_H263_BASELINE:
6929 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6930 break;
6931 default:
6932 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6933 return false;
6934 }
6935 }
6936 }
6937
6938 if (*eLevel == 0 && !m_level_set) {
6939 *eLevel = OMX_VIDEO_H263LevelMax;
6940 }
6941
6942 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
6943 profile_tbl = (unsigned int const *)h263_profile_level_table;
6944 } else {
6945 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
6946 return false;
6947 }
6948 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6949 if (*eProfile == 0) {
6950 *eProfile = OMX_VIDEO_VP8ProfileMain;
6951 } else {
6952 switch (codec_profile.profile) {
6953 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6954 *eProfile = OMX_VIDEO_VP8ProfileMain;
6955 break;
6956 default:
6957 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
6958 return false;
6959 }
6960 }
6961 if (*eLevel == 0) {
6962 switch (profile_level.level) {
6963 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6964 *eLevel = OMX_VIDEO_VP8Level_Version0;
6965 break;
6966 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6967 *eLevel = OMX_VIDEO_VP8Level_Version1;
6968 break;
6969 default:
6970 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
6971 return false;
6972 }
6973 }
6974 return true;
6975 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6976 if (*eProfile == 0) {
6977 if (!m_profile_set) {
6978 *eProfile = OMX_VIDEO_HEVCProfileMain;
6979 } else {
6980 switch (codec_profile.profile) {
6981 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6982 *eProfile = OMX_VIDEO_HEVCProfileMain;
6983 break;
6984 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6985 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6986 break;
6987 default:
6988 DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
6989 return false;
6990 }
6991 }
6992 }
6993
6994 if (*eLevel == 0 && !m_level_set) {
6995 *eLevel = OMX_VIDEO_HEVCLevelMax;
6996 }
6997
6998 if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
6999 profile_tbl = (unsigned int const *)hevc_profile_level_table;
7000 } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
7001 profile_tbl = (unsigned int const *)
7002 (&hevc_profile_level_table[HEVC_MAIN10_START]);
7003 } else {
7004 DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
7005 return false;
7006 }
7007 } else {
7008 DEBUG_PRINT_ERROR("Invalid codec type");
7009 return false;
7010 }
7011
7012 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
7013 ((m_sVenc_cfg.dvs_width + 15)>> 4);
7014
7015 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
7016 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
7017 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7018
7019 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
7020 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7021
7022 {
7023 new_level = profile_level.level;
7024 new_profile = codec_profile.profile;
7025 return true;
7026 }
7027 }
7028
7029 if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
7030 *eLevel = rc_off_level; //No level calculation for RC_OFF
7031 profile_level_found = true;
7032 return true;
7033 }
7034
7035 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
7036
7037 bool h264, ltr, hlayers;
7038 unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
7039 h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
7040 ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7041 hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
7042 ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
7043
7044 /* Hybrid HP reference buffers:
7045 layers = 1, 2 need 1 reference buffer
7046 layers = 3, 4 need 2 reference buffers
7047 layers = 5, 6 need 3 reference buffers
7048 */
7049
7050 if(hier_layers.hier_mode == HIER_P_HYBRID)
7051 hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
7052
7053 do {
7054 if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
7055 if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
7056 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
7057 if (h264 && (ltr || hlayers || hybridp)) {
7058 // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
7059 new_level = (int)profile_tbl[3];
7060 new_profile = (int)profile_tbl[4];
7061 profile_level_found = true;
7062 DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
7063 ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
7064 MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7065 break;
7066 } else {
7067 new_level = (int)profile_tbl[3];
7068 new_profile = (int)profile_tbl[4];
7069 profile_level_found = true;
7070 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
7071 break;
7072 }
7073 }
7074 }
7075 }
7076 profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
7077 } while (profile_tbl[0] != 0);
7078
7079 if (profile_level_found != true) {
7080 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
7081 return false;
7082 }
7083
7084 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
7085 || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
7086 || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
7087 *eLevel = new_level;
7088 }
7089
7090 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
7091 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
7092
7093 return true;
7094 }
7095 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)7096 bool venc_dev::venc_set_meta_mode(bool mode)
7097 {
7098 metadatamode = mode;
7099 return true;
7100 }
7101 #endif
7102
venc_is_video_session_supported(unsigned long width,unsigned long height)7103 bool venc_dev::venc_is_video_session_supported(unsigned long width,
7104 unsigned long height)
7105 {
7106 if ((width * height < capability.min_width * capability.min_height) ||
7107 (width * height > capability.max_width * capability.max_height)) {
7108 DEBUG_PRINT_ERROR(
7109 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
7110 width, height, capability.min_width, capability.min_height,
7111 capability.max_width, capability.max_height);
7112 return false;
7113 }
7114
7115 DEBUG_PRINT_LOW("video session supported");
7116 return true;
7117 }
7118
venc_set_batch_size(OMX_U32 batchSize)7119 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
7120 {
7121 struct v4l2_control control;
7122 int ret;
7123
7124 control.id = V4L2_CID_VIDC_QBUF_MODE;
7125 control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
7126
7127 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
7128 if (ret) {
7129 DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
7130 return false;
7131 }
7132
7133 mBatchSize = batchSize;
7134 DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
7135 return true;
7136 }
7137
BatchInfo()7138 venc_dev::BatchInfo::BatchInfo()
7139 : mNumPending(0) {
7140 pthread_mutex_init(&mLock, NULL);
7141 for (int i = 0; i < kMaxBufs; ++i) {
7142 mBufMap[i] = kBufIDFree;
7143 }
7144 }
7145
registerBuffer(int bufferId)7146 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
7147 pthread_mutex_lock(&mLock);
7148 int availId = 0;
7149 for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
7150 if (availId >= kMaxBufs) {
7151 DEBUG_PRINT_ERROR("Failed to find free entry !");
7152 pthread_mutex_unlock(&mLock);
7153 return -1;
7154 }
7155 mBufMap[availId] = bufferId;
7156 mNumPending++;
7157 pthread_mutex_unlock(&mLock);
7158 return availId;
7159 }
7160
retrieveBufferAt(int v4l2Id)7161 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
7162 pthread_mutex_lock(&mLock);
7163 if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
7164 DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
7165 pthread_mutex_unlock(&mLock);
7166 return -1;
7167 }
7168 if (mBufMap[v4l2Id] == kBufIDFree) {
7169 DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
7170 pthread_mutex_unlock(&mLock);
7171 return -1;
7172 }
7173 int bufferId = mBufMap[v4l2Id];
7174 mBufMap[v4l2Id] = kBufIDFree;
7175 mNumPending--;
7176 pthread_mutex_unlock(&mLock);
7177 return bufferId;
7178 }
7179
isPending(int bufferId)7180 bool venc_dev::BatchInfo::isPending(int bufferId) {
7181 pthread_mutex_lock(&mLock);
7182 int existsId = 0;
7183 for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
7184 pthread_mutex_unlock(&mLock);
7185 return existsId < kMaxBufs;
7186 }
7187
getFdAt(native_handle_t * hnd,int index)7188 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
7189 int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
7190 return fd;
7191 }
7192
getOffsetAt(native_handle_t * hnd,int index)7193 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
7194 int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
7195 return off;
7196 }
7197
getSizeAt(native_handle_t * hnd,int index)7198 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
7199 int size = hnd && (index + hnd->numFds) < hnd->numInts ?
7200 hnd->data[2*hnd->numFds + index] : -1;
7201 return size;
7202 }
7203
getColorFormatAt(native_handle_t * hnd,int index)7204 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
7205 int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
7206 hnd->data[3*hnd->numFds + index] : 0;
7207 return usage;
7208 }
7209
getTimeStampAt(native_handle_t * hnd,int index)7210 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
7211 int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
7212 hnd->data[4*hnd->numFds + index] : -1;
7213 return size;
7214 }
7215
7216 #ifdef _VQZIP_
venc_dev_vqzip()7217 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
7218 {
7219 mLibHandle = NULL;
7220 pthread_mutex_init(&lock, NULL);
7221 }
7222
init()7223 bool venc_dev::venc_dev_vqzip::init()
7224 {
7225 bool status = true;
7226 if (mLibHandle) {
7227 DEBUG_PRINT_ERROR("VQZIP init called twice");
7228 status = false;
7229 }
7230 if (status) {
7231 mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
7232 if (mLibHandle) {
7233 mVQZIPInit = (vqzip_init_t)
7234 dlsym(mLibHandle,"VQZipInit");
7235 mVQZIPDeInit = (vqzip_deinit_t)
7236 dlsym(mLibHandle,"VQZipDeInit");
7237 mVQZIPComputeStats = (vqzip_compute_stats_t)
7238 dlsym(mLibHandle,"VQZipComputeStats");
7239 if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
7240 status = false;
7241 } else {
7242 DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
7243 status = false;
7244 }
7245 if (status) {
7246 mVQZIPHandle = mVQZIPInit();
7247 }
7248 }
7249 if (!status && mLibHandle) {
7250 dlclose(mLibHandle);
7251 mLibHandle = NULL;
7252 mVQZIPHandle = NULL;
7253 mVQZIPInit = NULL;
7254 mVQZIPDeInit = NULL;
7255 mVQZIPComputeStats = NULL;
7256 }
7257 return status;
7258 }
7259
fill_stats_data(void * pBuf,void * extraData)7260 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
7261 {
7262 VQZipStatus result;
7263 VQZipStats *pStats = (VQZipStats *)extraData;
7264 pConfig.pSEIPayload = NULL;
7265 unsigned long size;
7266
7267 if (!pBuf || !pStats || !mVQZIPHandle) {
7268 DEBUG_PRINT_ERROR("Invalid data passed to stats function");
7269 }
7270 result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
7271 return (result < 0);
7272 }
7273
deinit()7274 void venc_dev::venc_dev_vqzip::deinit()
7275 {
7276 if (mLibHandle) {
7277 pthread_mutex_lock(&lock);
7278 dlclose(mLibHandle);
7279 mVQZIPDeInit(mVQZIPHandle);
7280 mLibHandle = NULL;
7281 mVQZIPHandle = NULL;
7282 mVQZIPInit = NULL;
7283 mVQZIPDeInit = NULL;
7284 mVQZIPComputeStats = NULL;
7285 pthread_mutex_unlock(&lock);
7286 }
7287 }
7288
~venc_dev_vqzip()7289 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
7290 {
7291 DEBUG_PRINT_HIGH("Destroy C2D instance");
7292 if (mLibHandle) {
7293 dlclose(mLibHandle);
7294 }
7295 mLibHandle = NULL;
7296 pthread_mutex_destroy(&lock);
7297 }
7298 #endif
7299
encExtradata(class omx_venc * venc_handle)7300 encExtradata::encExtradata(class omx_venc *venc_handle)
7301 {
7302 mCount = 0;
7303 mSize = 0;
7304 mUaddr = NULL;
7305 memset(&mIon, -1, sizeof(struct venc_ion));
7306 memset(mIndex, 0, sizeof(mIndex));
7307 mVencHandle = venc_handle;
7308 mDbgEtbCount = 0;
7309 pthread_mutex_init(&lock, NULL);
7310 vqzip_sei_found = false;
7311 }
7312
~encExtradata()7313 encExtradata::~encExtradata()
7314 {
7315 __free();
7316 mCount = 0;
7317 mSize = 0;
7318 mVencHandle = NULL;
7319 pthread_mutex_destroy(&lock);
7320 }
7321
__allocate()7322 OMX_ERRORTYPE encExtradata::__allocate()
7323 {
7324 ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
7325 if (!mVencHandle) {
7326 return OMX_ErrorInsufficientResources;
7327 }
7328 if (mUaddr || !totalSize) {
7329 return OMX_ErrorNone;
7330 }
7331 mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
7332 totalSize,
7333 &mIon.ion_alloc_data,
7334 &mIon.fd_ion_data, 0);
7335 if (mIon.ion_device_fd < 0) {
7336 DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
7337 DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
7338 return OMX_ErrorInsufficientResources;
7339 }
7340 mUaddr = (char *)mmap(NULL, totalSize,
7341 PROT_READ|PROT_WRITE, MAP_SHARED,
7342 mIon.fd_ion_data.fd , 0);
7343 if (mUaddr == MAP_FAILED) {
7344 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
7345 close(mIon.fd_ion_data.fd);
7346 mVencHandle->free_ion_memory(&mIon);
7347 return OMX_ErrorInsufficientResources;
7348 }
7349 for (unsigned i = 0; i < mCount; i++) {
7350 mIndex[i].status = FREE;
7351 mIndex[i].cookie = NULL;
7352 }
7353 return OMX_ErrorNone;
7354 }
7355
__get(char ** userptr,int * fd,unsigned * offset,ssize_t * size,int type)7356 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
7357 {
7358 unsigned i = 0;
7359 if (__allocate() != OMX_ErrorNone) {
7360 return -1;
7361 }
7362 for (i = 0; i < mCount; i++) {
7363 if (mIndex[i].status == type) {
7364 mIndex[i].status = BUSY;
7365 break;
7366 }
7367 }
7368 if (i >= mCount) {
7369 DEBUG_PRINT_HIGH("No Free extradata available");
7370 return -1;
7371 }
7372 *userptr = mUaddr + i * mSize;
7373 *fd = mIon.fd_ion_data.fd;
7374 *offset = i * mSize;
7375 *size = mSize;
7376 return i;
7377 }
7378
get(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7379 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
7380 int index;
7381 *userptr = NULL;
7382 *fd = -1;
7383 *offset = 0;
7384 *size = 0;
7385 pthread_mutex_lock(&lock);
7386 index = __get(userptr, fd, offset, size, FREE);
7387 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7388 pthread_mutex_unlock(&lock);
7389 return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
7390 }
7391
get(void * cookie,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7392 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
7393 {
7394 OMX_ERRORTYPE rc = OMX_ErrorNone;
7395 unsigned int i;
7396 *userptr = NULL;
7397 *fd = -1;
7398 *offset = 0;
7399 *size = 0;
7400 pthread_mutex_lock(&lock);
7401 for (i = 0; i < mCount; i++) {
7402 if (mIndex[i].cookie == cookie) {
7403 break;
7404 }
7405 }
7406 if (i < mCount) {
7407 *userptr = mUaddr + i * mSize;
7408 *fd = mIon.fd_ion_data.fd;
7409 *offset = i * mSize;
7410 *size = mSize;
7411 } else {
7412 int index = __get(userptr, fd, offset, size, FREE);
7413 if (index < 0 ) {
7414 DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
7415 __debug();
7416 rc = OMX_ErrorInsufficientResources;
7417 }
7418 }
7419 DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
7420 pthread_mutex_unlock(&lock);
7421 return rc;
7422 }
7423
getForConfig(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7424 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
7425 {
7426 OMX_ERRORTYPE rc = OMX_ErrorNone;
7427 unsigned int i;
7428 int found = -1;
7429 pthread_mutex_lock(&lock);
7430 found = __get(userptr, fd, offset, size, FOR_CONFIG);
7431 if (found < 0) {
7432 found = __get(userptr, fd, offset, size, FREE);
7433 }
7434
7435 if (found < 0) {
7436 DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
7437 __debug();
7438 rc = OMX_ErrorInsufficientResources;
7439 } else {
7440 mIndex[found].status = FOR_CONFIG;
7441 DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
7442 }
7443 pthread_mutex_unlock(&lock);
7444 return rc;
7445 }
7446
put(char * userptr)7447 OMX_ERRORTYPE encExtradata::put(char *userptr)
7448 {
7449 OMX_ERRORTYPE rc = OMX_ErrorNone;
7450 int index = (userptr - mUaddr)/mSize;
7451 pthread_mutex_lock(&lock);
7452 if (!userptr) {
7453 DEBUG_PRINT_HIGH("Userptr is NULL");
7454 rc = OMX_ErrorBadParameter;
7455 } else if (index < 0) {
7456 DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
7457 __debug();
7458 rc = OMX_ErrorBadParameter;
7459 } else {
7460 mIndex[index].status = FREE;
7461 mIndex[index].cookie = NULL;
7462 DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
7463 }
7464 pthread_mutex_unlock(&lock);
7465 return rc;
7466 }
7467
peek(unsigned index,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7468 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
7469 {
7470 OMX_ERRORTYPE rc = OMX_ErrorNone;
7471 *userptr = 0;
7472 *fd = -1;
7473 *offset = 0;
7474 *size = 0;
7475 pthread_mutex_lock(&lock);
7476 if (index < mCount) {
7477 rc = __allocate();
7478 if (rc == OMX_ErrorNone) {
7479 *userptr = mUaddr + index * mSize;
7480 *fd = mIon.fd_ion_data.fd;
7481 *offset = index * mSize;
7482 *size = mSize;
7483 }
7484 }
7485 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7486 pthread_mutex_unlock(&lock);
7487 return rc;
7488 }
7489
setCookieForConfig(void * cookie)7490 void encExtradata::setCookieForConfig(void *cookie)
7491 {
7492 char *userptr;
7493 int fd;
7494 unsigned offset;
7495 ssize_t size;
7496 pthread_mutex_lock(&lock);
7497 int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
7498 if (found >= 0) {
7499 mIndex[found].cookie = cookie;
7500 } else {
7501 DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
7502 found, cookie);
7503 __debug();
7504 }
7505 mDbgEtbCount++;
7506 pthread_mutex_unlock(&lock);
7507 }
7508
__free()7509 void encExtradata::__free()
7510 {
7511 ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
7512 if (mUaddr) {
7513 munmap((void *)mUaddr, totalSize);
7514 mUaddr = NULL;
7515 }
7516 if (mIon.fd_ion_data.fd >= 0) {
7517 if (mVencHandle)
7518 mVencHandle->free_ion_memory(&mIon);
7519 close(mIon.fd_ion_data.fd);
7520 mIon.fd_ion_data.fd = -1;
7521 }
7522 for (unsigned i = 0; i < mCount; i++) {
7523 mIndex[i].status = FREE;
7524 mIndex[i].cookie = NULL;
7525 }
7526 }
7527
update(unsigned int count,ssize_t size)7528 void encExtradata::update(unsigned int count, ssize_t size)
7529 {
7530 pthread_mutex_lock(&lock);
7531 __free();
7532 mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
7533 mSize = size;
7534 DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
7535 pthread_mutex_unlock(&lock);
7536 }
7537
__debug()7538 void encExtradata::__debug()
7539 {
7540 DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
7541 this, mCount, mSize, mUaddr, mVencHandle);
7542 for (unsigned i = 0; i < mCount; i++) {
7543 DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
7544 }
7545 }
7546
getBufferSize()7547 ssize_t encExtradata::getBufferSize()
7548 {
7549 return mSize;
7550 }
7551
getBufferCount()7552 unsigned int encExtradata::getBufferCount()
7553 {
7554 return mCount;
7555 }
7556