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 // color_format == 1 ==> RGBA to YUV Color-converted buffer
3655 // Buffers color-converted via C2D have 601-Limited color
3656 if (!streaming[OUTPUT_PORT]) {
3657 DEBUG_PRINT_HIGH("Setting colorspace 601-L for Color-converted buffer");
3658 venc_set_colorspace(MSM_VIDC_BT601_6_625, 0 /*range-limited*/,
3659 MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
3660 }
3661 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3662 plane[0].data_offset = bufhdr->nOffset;
3663 plane[0].length = bufhdr->nAllocLen;
3664 plane[0].bytesused = bufhdr->nFilledLen;
3665 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
3666 fd, plane[0].bytesused, plane[0].length);
3667 }
3668 } else {
3669 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
3670 plane[0].data_offset = bufhdr->nOffset;
3671 plane[0].length = bufhdr->nAllocLen;
3672 plane[0].bytesused = bufhdr->nFilledLen;
3673 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
3674 fd, plane[0].bytesused, plane[0].length);
3675 }
3676 }
3677
3678 extra_idx = EXTRADATA_IDX(num_input_planes);
3679
3680 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3681 char *userptr;
3682 int fd;
3683 unsigned offset;
3684 ssize_t size;
3685 int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
3686 if (rc != OMX_ErrorNone) {
3687 DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
3688 return rc;
3689 }
3690 plane[extra_idx].bytesused = 0;
3691 plane[extra_idx].length = size;
3692 plane[extra_idx].m.userptr = (unsigned long) userptr;
3693 #ifdef USE_ION
3694 plane[extra_idx].reserved[0] = fd;
3695 #endif
3696 plane[extra_idx].reserved[1] = offset;
3697 plane[extra_idx].data_offset = 0;
3698 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3699 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3700 return false;
3701 }
3702
3703 if (!streaming[OUTPUT_PORT]) {
3704 enum v4l2_buf_type buf_type;
3705 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3706 int ret;
3707 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3708
3709 if (ret) {
3710 DEBUG_PRINT_ERROR("Failed to call streamon");
3711 if (errno == EBUSY) {
3712 hw_overload = true;
3713 }
3714 return false;
3715 } else {
3716 streaming[OUTPUT_PORT] = true;
3717 }
3718 }
3719
3720 buf.index = index;
3721 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3722 buf.memory = V4L2_MEMORY_USERPTR;
3723 plane[0].reserved[0] = fd;
3724 plane[0].reserved[1] = 0;
3725 buf.m.planes = plane;
3726 buf.length = num_input_planes;
3727
3728 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3729 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3730
3731 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3732 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3733 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3734
3735 if (rc) {
3736 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3737 return false;
3738 }
3739
3740 etb++;
3741
3742 if (m_debug.in_buffer_log) {
3743 venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
3744 }
3745
3746 return true;
3747 }
3748
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3749 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3750 {
3751 struct v4l2_buffer buf;
3752 struct v4l2_plane plane;
3753 int rc = 0;
3754 struct v4l2_control control;
3755 encoder_media_buffer_type * meta_buf = NULL;
3756 native_handle_t *hnd = NULL;
3757
3758 if (bufhdr == NULL) {
3759 DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3760 return false;
3761 }
3762
3763 bool status = true;
3764 if (metadatamode) {
3765 plane.m.userptr = (unsigned long)bufhdr->pBuffer;
3766 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
3767
3768 if (!color_format) {
3769 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
3770 hnd = (native_handle_t*)meta_buf->meta_handle;
3771 if (!hnd) {
3772 DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3773 return false;
3774 } else if (hnd->numFds > kMaxBuffersInBatch) {
3775 DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3776 "Max = %d", hnd->numFds, kMaxBuffersInBatch);
3777 status = false;
3778 }
3779 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
3780 } else {
3781 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3782 status = false;
3783 }
3784 } else {
3785 DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3786 status = false;
3787 }
3788 } else {
3789 DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3790 status = false;
3791 }
3792
3793 if (status) {
3794 OMX_TICKS bufTimeStamp = 0ll;
3795 int numBufs = hnd->numFds;
3796 int v4l2Ids[kMaxBuffersInBatch] = {-1};
3797 for (int i = 0; i < numBufs; ++i) {
3798 v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3799 if (v4l2Ids[i] < 0) {
3800 DEBUG_PRINT_ERROR("Failed to register buffer");
3801 // TODO: cleanup the map and purge all slots of current index
3802 status = false;
3803 break;
3804 }
3805 }
3806 for (int i = 0; i < numBufs; ++i) {
3807 int v4l2Id = v4l2Ids[i];
3808
3809 memset(&buf, 0, sizeof(buf));
3810 memset(&plane, 0, sizeof(plane));
3811
3812 DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3813 buf.index = (unsigned)v4l2Id;
3814 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3815 buf.memory = V4L2_MEMORY_USERPTR;
3816 plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
3817 plane.reserved[1] = 0;
3818 plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
3819 plane.m.userptr = (unsigned long)meta_buf;
3820 plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
3821 buf.m.planes = &plane;
3822 buf.length = 1;
3823
3824 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3825 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
3826 if (i != numBufs - 1) {
3827 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3828 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
3829 i, etb + 1, numBufs);
3830 }
3831
3832
3833 // timestamp differences from camera are in nano-seconds
3834 bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
3835
3836 DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3837 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
3838 buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3839 buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3840
3841 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3842 if (rc) {
3843 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3844 return false;
3845 }
3846
3847 etb++;
3848 }
3849 }
3850
3851 if (status && !streaming[OUTPUT_PORT]) {
3852 enum v4l2_buf_type buf_type;
3853 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3854 int ret;
3855 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3856 if (ret) {
3857 DEBUG_PRINT_ERROR("Failed to call streamon");
3858 if (errno == EBUSY) {
3859 hw_overload = true;
3860 }
3861 status = false;
3862 } else {
3863 streaming[OUTPUT_PORT] = true;
3864 }
3865 }
3866
3867 return status;
3868 }
3869
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3870 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3871 {
3872 struct pmem *temp_buffer = NULL;
3873 struct venc_buffer frameinfo;
3874 struct v4l2_buffer buf;
3875 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3876 int rc = 0;
3877 unsigned int extra_idx;
3878 struct OMX_BUFFERHEADERTYPE *bufhdr;
3879
3880 if (buffer == NULL)
3881 return false;
3882
3883 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3884
3885 if (pmem_data_buf) {
3886 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3887 plane[0].m.userptr = (unsigned long)pmem_data_buf;
3888 } else {
3889 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3890 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3891 }
3892
3893 memset(&buf, 0, sizeof(buf));
3894 memset(&plane, 0, sizeof(plane));
3895
3896 buf.index = index;
3897 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3898 buf.memory = V4L2_MEMORY_USERPTR;
3899 plane[0].length = bufhdr->nAllocLen;
3900 plane[0].bytesused = bufhdr->nFilledLen;
3901 plane[0].reserved[0] = fd;
3902 plane[0].reserved[1] = 0;
3903 plane[0].data_offset = bufhdr->nOffset;
3904 buf.m.planes = plane;
3905 buf.length = num_output_planes;
3906 buf.flags = 0;
3907
3908 if (mBatchSize) {
3909 // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
3910 // This results in the first batch being of size mBatchSize + 1, but thats good because
3911 // we need an extra FTB for the codec specific data.
3912
3913 if (!ftb || ftb % mBatchSize) {
3914 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
3915 DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
3916 }
3917 }
3918
3919 extra_idx = EXTRADATA_IDX(num_output_planes);
3920
3921 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3922 char *userptr;
3923 int fd;
3924 unsigned offset;
3925 ssize_t size;
3926 int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
3927 if (rc != OMX_ErrorNone) {
3928 DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
3929 return false;
3930 }
3931 plane[extra_idx].bytesused = 0;
3932 plane[extra_idx].length = size;
3933 plane[extra_idx].m.userptr = (unsigned long)userptr;
3934 #ifdef USE_ION
3935 plane[extra_idx].reserved[0] = fd;
3936 #endif
3937 plane[extra_idx].reserved[1] = offset;
3938 plane[extra_idx].data_offset = 0;
3939 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3940 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3941 return false;
3942 }
3943
3944 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3945
3946 if (rc) {
3947 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3948 return false;
3949 }
3950
3951 ftb++;
3952 return true;
3953 }
3954
venc_set_inband_video_header(OMX_BOOL enable)3955 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
3956 {
3957 struct v4l2_control control;
3958
3959 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
3960 if(enable) {
3961 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
3962 } else {
3963 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
3964 }
3965
3966 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
3967 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3968 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
3969 return false;
3970 }
3971 return true;
3972 }
3973
venc_set_au_delimiter(OMX_BOOL enable)3974 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
3975 {
3976 struct v4l2_control control;
3977
3978 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
3979 if(enable) {
3980 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
3981 } else {
3982 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
3983 }
3984
3985 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
3986 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
3987 DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
3988 return false;
3989 }
3990 return true;
3991 }
3992
venc_set_mbi_statistics_mode(OMX_U32 mode)3993 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
3994 {
3995 struct v4l2_control control;
3996
3997 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
3998 control.value = mode;
3999
4000 DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
4001 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
4002 DEBUG_PRINT_ERROR("Setting MBI mode failed");
4003 return false;
4004 }
4005 return true;
4006 }
4007
venc_set_vqzip_sei_type(OMX_BOOL enable)4008 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
4009 {
4010 struct v4l2_control sei_control, yuvstats_control;
4011
4012 DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
4013 sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
4014 yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4015
4016 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
4017 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
4018 }
4019
4020 if(enable) {
4021 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
4022 yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4023 } else {
4024 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
4025 yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
4026 }
4027
4028 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
4029 DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
4030 }
4031
4032 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
4033 DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
4034 }
4035 #ifdef _VQZIP_
4036 vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
4037 vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
4038 vqzip.init();
4039 vqzip_sei_info.enabled = true;
4040 #endif
4041
4042 return true;
4043 }
4044
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)4045 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
4046 {
4047 // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
4048 if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
4049 return false;
4050
4051 // Check for bframes with Hier-P-Hybrid
4052 if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
4053 return false;
4054
4055 // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
4056 if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
4057 hier_layers.hier_mode == HIER_B || ltrinfo.count))
4058 return false;
4059
4060 // Check for LTR with Hier-P-Hybrid
4061 if (count && hier_layers.hier_mode == HIER_P_HYBRID)
4062 return false;
4063
4064 return true;
4065 }
4066
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)4067 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
4068 OMX_U32 num_layers)
4069 {
4070 struct v4l2_control control;
4071
4072 if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
4073 DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
4074 return false;
4075 }
4076
4077 if (type == QOMX_HIERARCHICALCODING_P) {
4078 // Reduce layer count by 1 before sending to driver. This avoids
4079 // driver doing the same in multiple places.
4080 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
4081 control.value = num_layers - 1;
4082 DEBUG_PRINT_HIGH("Set MAX 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 MAX Hier P num layers failed");
4085 return false;
4086 }
4087 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
4088 control.value = num_layers - 1;
4089 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
4090 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4091 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4092 return false;
4093 }
4094 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4095 DEBUG_PRINT_LOW("Set H264_SVC_NAL");
4096 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4097 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4098 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4099 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4100 return false;
4101 }
4102 }
4103 hier_layers.hier_mode = HIER_P;
4104 } else if (type == QOMX_HIERARCHICALCODING_B) {
4105 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4106 DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
4107 return false;
4108 }
4109 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
4110 control.value = num_layers - 1;
4111 DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
4112 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4113 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
4114 return false;
4115 }
4116 hier_layers.hier_mode = HIER_B;
4117 } else {
4118 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
4119 return false;
4120 }
4121 hier_layers.numlayers = num_layers;
4122 return true;
4123 }
4124
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)4125 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
4126 {
4127 struct v4l2_control control;
4128
4129 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
4130
4131 if (enable == OMX_FALSE) {
4132 /* No easy way to turn off extradata to the driver
4133 * at the moment */
4134 return false;
4135 }
4136
4137 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4138 switch (extra_data) {
4139 case OMX_ExtraDataVideoEncoderSliceInfo:
4140 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
4141 break;
4142 case OMX_ExtraDataVideoEncoderMBInfo:
4143 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
4144 break;
4145 case OMX_ExtraDataFrameDimension:
4146 control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
4147 break;
4148 default:
4149 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
4150 return false;
4151 }
4152
4153 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4154 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
4155 (unsigned int)extra_data, errno);
4156 return false;
4157 }
4158
4159 return true;
4160 }
4161
venc_set_slice_delivery_mode(OMX_U32 enable)4162 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
4163 {
4164 struct v4l2_control control;
4165
4166 if (enable) {
4167 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
4168 control.value = 1;
4169 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
4170
4171 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4172 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4173 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
4174 return false;
4175 } else {
4176 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
4177 slice_mode.enable = 1;
4178 }
4179 } else {
4180 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
4181 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
4182 m_sVenc_cfg.codectype);
4183 }
4184 } else {
4185 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
4186 }
4187
4188 return true;
4189 }
4190
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)4191 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
4192 {
4193 int rc;
4194 struct v4l2_control control;
4195 struct v4l2_ext_control ctrl[4];
4196 struct v4l2_ext_controls controls;
4197
4198 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
4199 ctrl[0].value = initqp->nQpI;
4200 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
4201 ctrl[1].value = initqp->nQpP;
4202 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
4203 ctrl[2].value = initqp->nQpB;
4204 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
4205 ctrl[3].value = initqp->bEnableInitQp;
4206
4207 controls.count = 4;
4208 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4209 controls.controls = ctrl;
4210
4211 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4212 controls.controls[0].id, controls.controls[0].value,
4213 controls.controls[1].id, controls.controls[1].value,
4214 controls.controls[2].id, controls.controls[2].value,
4215 controls.controls[3].id, controls.controls[3].value);
4216
4217 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4218 if (rc) {
4219 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
4220 return false;
4221 }
4222
4223 init_qp.iframeqp = initqp->nQpI;
4224 init_qp.pframeqp = initqp->nQpP;
4225 init_qp.bframeqp = initqp->nQpB;
4226 init_qp.enableinitqp = initqp->bEnableInitQp;
4227
4228 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
4229 controls.controls[0].id, controls.controls[0].value,
4230 controls.controls[1].id, controls.controls[1].value,
4231 controls.controls[2].id, controls.controls[2].value,
4232 controls.controls[3].id, controls.controls[3].value);
4233 return true;
4234 }
4235
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)4236 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
4237 OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
4238 {
4239 int rc;
4240 struct v4l2_control control;
4241
4242 DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
4243 primaries, range, transfer_chars, matrix_coeffs);
4244
4245 control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
4246 control.value = primaries;
4247
4248 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4249 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4250
4251 if (rc) {
4252 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
4253 return false;
4254 }
4255
4256 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4257
4258 color_space.primaries = control.value;
4259
4260 control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
4261 control.value = range;
4262
4263 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4264 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4265
4266 if (rc) {
4267 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
4268 return false;
4269 }
4270
4271 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4272
4273 color_space.range = control.value;
4274
4275 control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
4276 control.value = transfer_chars;
4277
4278 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4279 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4280
4281 if (rc) {
4282 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
4283 return false;
4284 }
4285
4286 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4287
4288 color_space.transfer_chars = control.value;
4289
4290 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
4291 control.value = matrix_coeffs;
4292
4293 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4294 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4295
4296 if (rc) {
4297 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
4298 return false;
4299 }
4300
4301 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4302
4303 color_space.matrix_coeffs = control.value;
4304
4305 return true;
4306 }
4307
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)4308 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
4309 {
4310 int rc;
4311 struct v4l2_control control;
4312
4313 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
4314 control.value = i_frame_qp;
4315
4316 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4317 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4318
4319 if (rc) {
4320 DEBUG_PRINT_ERROR("Failed to set control");
4321 return false;
4322 }
4323
4324 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4325 session_qp.iframeqp = control.value;
4326
4327 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
4328 control.value = p_frame_qp;
4329
4330 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4331 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4332
4333 if (rc) {
4334 DEBUG_PRINT_ERROR("Failed to set control");
4335 return false;
4336 }
4337
4338 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4339
4340 session_qp.pframeqp = control.value;
4341
4342 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
4343 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4344
4345 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
4346 control.value = b_frame_qp;
4347
4348 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4349 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4350
4351 if (rc) {
4352 DEBUG_PRINT_ERROR("Failed to set control");
4353 return false;
4354 }
4355
4356 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4357
4358 session_qp.bframeqp = control.value;
4359 }
4360
4361 return true;
4362 }
4363
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)4364 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
4365 {
4366 int rc;
4367 struct v4l2_control control;
4368
4369 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
4370
4371 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
4373 else
4374 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
4375 control.value = min_qp;
4376
4377 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
4378 control.id, control.value);
4379 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4380 if (rc) {
4381 DEBUG_PRINT_ERROR("Failed to set control");
4382 return false;
4383 }
4384
4385 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
4386 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
4387 else
4388 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
4389 control.value = max_qp;
4390
4391 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
4392 control.id, control.value);
4393 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4394 if (rc) {
4395 DEBUG_PRINT_ERROR("Failed to set control");
4396 return false;
4397 }
4398 } else {
4399 DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
4400 (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
4401 }
4402
4403 return true;
4404 }
4405
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)4406 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
4407 {
4408 struct venc_profile requested_profile = {0};
4409 struct ven_profilelevel requested_level = {0};
4410 unsigned long mb_per_frame = 0;
4411 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
4412 (unsigned int)eProfile, (unsigned int)eLevel);
4413 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4414 ((m_sVenc_cfg.dvs_width + 15) >> 4);
4415
4416 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
4417 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
4418 return true;
4419 }
4420
4421 if (vqzip_sei_info.enabled) {
4422 DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
4423 return true;
4424 }
4425
4426 DEBUG_PRINT_LOW("Validating Profile/Level from table");
4427
4428 if (!venc_validate_profile_level(&eProfile, &eLevel)) {
4429 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
4430 return false;
4431 }
4432
4433 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4434 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
4435 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
4436 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
4437
4438 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4439 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
4440 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4441 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
4442 } else {
4443 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
4444 (unsigned int)eProfile);
4445 return false;
4446 }
4447
4448 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
4449 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
4450 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
4451 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
4452
4453 if (mb_per_frame >= 3600) {
4454 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4455 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4456
4457 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4458 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4459 } else {
4460 switch (eLevel) {
4461 case OMX_VIDEO_MPEG4Level0:
4462 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
4463 break;
4464 case OMX_VIDEO_MPEG4Level0b:
4465 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
4466 break;
4467 case OMX_VIDEO_MPEG4Level1:
4468 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
4469 break;
4470 case OMX_VIDEO_MPEG4Level2:
4471 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
4472 break;
4473 case OMX_VIDEO_MPEG4Level3:
4474 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
4475 break;
4476 case OMX_VIDEO_MPEG4Level4a:
4477 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
4478 break;
4479 case OMX_VIDEO_MPEG4Level5:
4480 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4481 break;
4482 default:
4483 return false;
4484 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
4485 break;
4486 }
4487 }
4488 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4489
4490 switch (eProfile) {
4491 case OMX_VIDEO_H263ProfileBaseline:
4492 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
4493 break;
4494 case OMX_VIDEO_H263ProfileH320Coding:
4495 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
4496 break;
4497 case OMX_VIDEO_H263ProfileBackwardCompatible:
4498 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
4499 break;
4500 case OMX_VIDEO_H263ProfileISWV2:
4501 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
4502 break;
4503 case OMX_VIDEO_H263ProfileISWV3:
4504 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
4505 break;
4506 case OMX_VIDEO_H263ProfileHighCompression:
4507 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
4508 break;
4509 case OMX_VIDEO_H263ProfileInternet:
4510 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
4511 break;
4512 case OMX_VIDEO_H263ProfileInterlace:
4513 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
4514 break;
4515 case OMX_VIDEO_H263ProfileHighLatency:
4516 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
4517 break;
4518 default:
4519 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
4520 requested_profile.profile);
4521 return false;
4522 }
4523
4524 //profile level
4525 switch (eLevel) {
4526 case OMX_VIDEO_H263Level10:
4527 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
4528 break;
4529 case OMX_VIDEO_H263Level20:
4530 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
4531 break;
4532 case OMX_VIDEO_H263Level30:
4533 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
4534 break;
4535 case OMX_VIDEO_H263Level40:
4536 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
4537 break;
4538 case OMX_VIDEO_H263Level45:
4539 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
4540 break;
4541 case OMX_VIDEO_H263Level50:
4542 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
4543 break;
4544 case OMX_VIDEO_H263Level60:
4545 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
4546 break;
4547 case OMX_VIDEO_H263Level70:
4548 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
4549 break;
4550 default:
4551 return false;
4552 break;
4553 }
4554 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4555 if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
4556 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
4557 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
4558 eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
4559 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
4560 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh ||
4561 eProfile == OMX_VIDEO_AVCProfileConstrainedHigh) {
4562 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
4563 } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
4564 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
4565 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
4566 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
4567 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
4568 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
4569 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
4570 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
4571 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
4572 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
4573 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
4574 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
4575 } else {
4576 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
4577 requested_profile.profile);
4578 return false;
4579 }
4580
4581 //profile level
4582 switch (eLevel) {
4583 case OMX_VIDEO_AVCLevel1:
4584 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
4585 break;
4586 case OMX_VIDEO_AVCLevel1b:
4587 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
4588 break;
4589 case OMX_VIDEO_AVCLevel11:
4590 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
4591 break;
4592 case OMX_VIDEO_AVCLevel12:
4593 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
4594 break;
4595 case OMX_VIDEO_AVCLevel13:
4596 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
4597 break;
4598 case OMX_VIDEO_AVCLevel2:
4599 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
4600 break;
4601 case OMX_VIDEO_AVCLevel21:
4602 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
4603 break;
4604 case OMX_VIDEO_AVCLevel22:
4605 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
4606 break;
4607 case OMX_VIDEO_AVCLevel3:
4608 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
4609 break;
4610 case OMX_VIDEO_AVCLevel31:
4611 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
4612 break;
4613 case OMX_VIDEO_AVCLevel32:
4614 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
4615 break;
4616 case OMX_VIDEO_AVCLevel4:
4617 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
4618 break;
4619 case OMX_VIDEO_AVCLevel41:
4620 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
4621 break;
4622 case OMX_VIDEO_AVCLevel42:
4623 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
4624 break;
4625 case OMX_VIDEO_AVCLevel5:
4626 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
4627 break;
4628 case OMX_VIDEO_AVCLevel51:
4629 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
4630 break;
4631 case OMX_VIDEO_AVCLevel52:
4632 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4633 break;
4634 case OMX_VIDEO_AVCLevelMax:
4635 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
4636 break;
4637 default :
4638 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
4639 requested_level.level);
4640 return false;
4641 break;
4642 }
4643 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4644 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
4645 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
4646 (unsigned int)eProfile);
4647 return false;
4648 }
4649 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
4650 m_profile_set = true;
4651 switch(eLevel) {
4652 case OMX_VIDEO_VP8Level_Version0:
4653 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
4654 break;
4655 case OMX_VIDEO_VP8Level_Version1:
4656 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
4657 break;
4658 default:
4659 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
4660 (unsigned int)eLevel);
4661 return false;
4662 break;
4663 }
4664 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4665 if (eProfile == OMX_VIDEO_HEVCProfileMain) {
4666 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
4667 } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
4668 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
4669 } else {
4670 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
4671 requested_profile.profile);
4672 return false;
4673 }
4674
4675 //profile level
4676 switch (eLevel) {
4677 case OMX_VIDEO_HEVCMainTierLevel1:
4678 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
4679 break;
4680 case OMX_VIDEO_HEVCHighTierLevel1:
4681 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
4682 break;
4683 case OMX_VIDEO_HEVCMainTierLevel2:
4684 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
4685 break;
4686 case OMX_VIDEO_HEVCHighTierLevel2:
4687 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
4688 break;
4689 case OMX_VIDEO_HEVCMainTierLevel21:
4690 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
4691 break;
4692 case OMX_VIDEO_HEVCHighTierLevel21:
4693 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
4694 break;
4695 case OMX_VIDEO_HEVCMainTierLevel3:
4696 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
4697 break;
4698 case OMX_VIDEO_HEVCHighTierLevel3:
4699 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
4700 break;
4701 case OMX_VIDEO_HEVCMainTierLevel31:
4702 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
4703 break;
4704 case OMX_VIDEO_HEVCHighTierLevel31:
4705 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
4706 break;
4707 case OMX_VIDEO_HEVCMainTierLevel4:
4708 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
4709 break;
4710 case OMX_VIDEO_HEVCHighTierLevel4:
4711 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
4712 break;
4713 case OMX_VIDEO_HEVCMainTierLevel41:
4714 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
4715 break;
4716 case OMX_VIDEO_HEVCHighTierLevel41:
4717 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
4718 break;
4719 case OMX_VIDEO_HEVCMainTierLevel5:
4720 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
4721 break;
4722 case OMX_VIDEO_HEVCHighTierLevel5:
4723 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
4724 break;
4725 case OMX_VIDEO_HEVCMainTierLevel51:
4726 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
4727 break;
4728 case OMX_VIDEO_HEVCHighTierLevel51:
4729 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
4730 break;
4731 case OMX_VIDEO_HEVCMainTierLevel52:
4732 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
4733 break;
4734 case OMX_VIDEO_HEVCHighTierLevel52:
4735 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
4736 break;
4737 case OMX_VIDEO_HEVCMainTierLevel6:
4738 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
4739 break;
4740 case OMX_VIDEO_HEVCHighTierLevel6:
4741 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
4742 break;
4743 case OMX_VIDEO_HEVCMainTierLevel61:
4744 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
4745 break;
4746 case OMX_VIDEO_HEVCHighTierLevel61:
4747 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
4748 break;
4749 default :
4750 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
4751 requested_level.level);
4752 return false;
4753 }
4754 }
4755
4756 if (!m_profile_set) {
4757 int rc;
4758 struct v4l2_control control;
4759
4760 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4761 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
4762 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4763 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
4764 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4765 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
4766 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
4768 } else {
4769 DEBUG_PRINT_ERROR("Wrong CODEC");
4770 return false;
4771 }
4772
4773 control.value = requested_profile.profile;
4774
4775 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4776 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4777
4778 if (rc) {
4779 DEBUG_PRINT_ERROR("Failed to set control");
4780 return false;
4781 }
4782
4783 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4784
4785 codec_profile.profile = control.value;
4786 m_profile_set = true;
4787 }
4788
4789 if (!m_level_set) {
4790 int rc;
4791 struct v4l2_control control;
4792
4793 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4794 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
4795 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4796 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
4797 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4798 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
4799 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4800 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
4801 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4802 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
4803 } else {
4804 DEBUG_PRINT_ERROR("Wrong CODEC");
4805 return false;
4806 }
4807
4808 control.value = requested_level.level;
4809
4810 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4811 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4812
4813 if (rc) {
4814 DEBUG_PRINT_ERROR("Failed to set control");
4815 return false;
4816 }
4817
4818 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4819
4820 profile_level.level = control.value;
4821 m_level_set = true;
4822 }
4823
4824 return true;
4825 }
4826
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)4827 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
4828 {
4829
4830 struct venc_voptimingcfg vop_timing_cfg;
4831
4832 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
4833 (unsigned int)TimeIncRes);
4834
4835 vop_timing_cfg.voptime_resolution = TimeIncRes;
4836
4837 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
4838 return true;
4839 }
4840
venc_set_intra_period_config(OMX_U32 nPFrames,OMX_U32 nBFrames)4841 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
4842 #if _ANDROID_
4843 // Android defines nBFrames as number of Bs between I OR P
4844 // Per the spec, nBFrames is number of Bs between I
4845 OMX_U32 nBs = nBFrames * (nPFrames + 1);
4846 DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
4847 nBFrames = nBs;
4848 #endif //_ANDROID_
4849 return venc_set_intra_period(nPFrames, nBFrames);
4850 }
4851
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)4852 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
4853 {
4854
4855 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
4856 int rc;
4857 struct v4l2_control control;
4858 int pframe = 0, bframe = 0;
4859
4860 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
4861 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
4862 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
4863 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
4864 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
4865 nBFrames=0;
4866 }
4867
4868 if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
4869 DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
4870 return false;
4871 }
4872
4873 intra_period.num_pframes = nPFrames;
4874 intra_period.num_bframes = nBFrames;
4875
4876 if (!venc_calibrate_gop() && !is_thulium_v1)
4877 {
4878 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4879 return false;
4880 }
4881
4882 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4883 control.value = intra_period.num_pframes;
4884 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4885
4886 if (rc) {
4887 DEBUG_PRINT_ERROR("Failed to set control");
4888 return false;
4889 }
4890
4891 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4892
4893 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4894 control.value = intra_period.num_bframes;
4895 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4896 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4897
4898 if (rc) {
4899 DEBUG_PRINT_ERROR("Failed to set control");
4900 return false;
4901 }
4902
4903 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
4904
4905 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
4906 m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4907 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4908 control.value = 1;
4909
4910 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4911
4912 if (rc) {
4913 DEBUG_PRINT_ERROR("Failed to set control");
4914 return false;
4915 }
4916 idrperiod.idrperiod = 1;
4917 }
4918 return true;
4919 }
4920
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)4921 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
4922 {
4923 int rc = 0;
4924 struct v4l2_control control;
4925 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
4926 (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
4927
4928 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
4929 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
4930 return false;
4931 }
4932
4933 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
4934 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4935 return false;
4936 }
4937
4938 if (!intra_period.num_bframes)
4939 intra_period.num_pframes = nPFrames;
4940 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
4941 control.value = nIDRPeriod;
4942
4943 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4944
4945 if (rc) {
4946 DEBUG_PRINT_ERROR("Failed to set control");
4947 return false;
4948 }
4949
4950 idrperiod.idrperiod = nIDRPeriod;
4951 return true;
4952 }
4953
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)4954 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
4955 {
4956 int rc = 0;
4957 struct v4l2_control control;
4958
4959 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
4960
4961 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
4962 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
4963
4964 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
4965 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
4966
4967 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4968 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4969
4970 if (rc) {
4971 DEBUG_PRINT_ERROR("Failed to set control");
4972 return false;
4973 }
4974
4975 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4976 entropy.longentropysel = control.value;
4977
4978 if (i_cabac_level == 0) {
4979 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
4980 } else if (i_cabac_level == 1) {
4981 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
4982 } else if (i_cabac_level == 2) {
4983 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
4984 }
4985
4986 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
4987 //control.value = entropy_cfg.cabacmodel;
4988 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4989 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4990
4991 if (rc) {
4992 DEBUG_PRINT_ERROR("Failed to set control");
4993 return false;
4994 }
4995
4996 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4997 entropy.cabacmodel=control.value;
4998 } else if (!enable) {
4999 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
5000 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
5001 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5002 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5003
5004 if (rc) {
5005 DEBUG_PRINT_ERROR("Failed to set control");
5006 return false;
5007 }
5008
5009 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5010 entropy.longentropysel=control.value;
5011 } else {
5012 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
5013 return false;
5014 }
5015
5016 return true;
5017 }
5018
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)5019 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
5020 {
5021 int rc;
5022 struct v4l2_control control;
5023 bool status = true;
5024
5025 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) {
5026 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
5027 } else {
5028 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5029 }
5030
5031 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5032 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5033 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5034
5035 if (rc) {
5036 DEBUG_PRINT_ERROR("Failed to set control");
5037 return false;
5038 }
5039
5040 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5041 multislice.mslice_mode=control.value;
5042
5043 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
5044
5045 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
5046 control.value = nSlicesize;
5047 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
5048 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5049
5050 if (rc) {
5051 DEBUG_PRINT_ERROR("Failed to set control");
5052 return false;
5053 }
5054
5055 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5056 multislice.mslice_size=control.value;
5057
5058 }
5059
5060 return status;
5061 }
5062
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)5063 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
5064 {
5065 bool status = true;
5066 int rc;
5067 struct v4l2_control control_mode,control_mbs;
5068 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
5069
5070 // There is no disabled mode. Disabled mode is indicated by a 0 count.
5071 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
5072 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
5073 return status;
5074 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
5075 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5076 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
5077 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
5078 control_mbs.value=irMBs;
5079 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
5080 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5081 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
5082 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5083 control_mbs.value=irMBs;
5084 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
5085 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5086 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
5087 } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
5088 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
5089 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
5090 control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
5091 control_mbs.value = irMBs;
5092 } else {
5093 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
5094 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
5095 return false;
5096 }
5097
5098 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
5099 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
5100
5101 if (rc) {
5102 DEBUG_PRINT_ERROR("Failed to set control");
5103 return false;
5104 }
5105
5106 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
5107
5108 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
5109 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
5110
5111 if (rc) {
5112 DEBUG_PRINT_ERROR("Failed to set control");
5113 return false;
5114 }
5115
5116 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
5117
5118 intra_refresh.irmode = control_mode.value;
5119 intra_refresh.mbcount = control_mbs.value;
5120
5121 return status;
5122 }
5123
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)5124 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
5125 {
5126 bool status = true;
5127 struct venc_headerextension hec_cfg;
5128 struct venc_multiclicecfg multislice_cfg;
5129 int rc;
5130 OMX_U32 resynchMarkerSpacingBytes = 0;
5131 struct v4l2_control control;
5132
5133 memset(&control, 0, sizeof(control));
5134
5135 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5136 if (error_resilience->bEnableHEC) {
5137 hec_cfg.header_extension = 1;
5138 } else {
5139 hec_cfg.header_extension = 0;
5140 }
5141
5142 hec.header_extension = error_resilience->bEnableHEC;
5143 }
5144
5145 if (error_resilience->bEnableRVLC) {
5146 DEBUG_PRINT_ERROR("RVLC is not Supported");
5147 return false;
5148 }
5149
5150 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5151 (error_resilience->bEnableDataPartitioning)) {
5152 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
5153 return false;
5154 }
5155
5156 if (error_resilience->nResynchMarkerSpacing) {
5157 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
5158 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
5159 }
5160 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
5161 (error_resilience->nResynchMarkerSpacing)) {
5162 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
5163 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5164 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5165 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
5166 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
5167 error_resilience->bEnableDataPartitioning) {
5168 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
5169 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
5170 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5171 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
5172 } else {
5173 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
5174 multislice_cfg.mslice_size = 0;
5175 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
5176 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
5177 }
5178
5179 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
5180 multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
5181 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5182 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5183
5184 if (rc) {
5185 DEBUG_PRINT_ERROR("Failed to set Slice mode control");
5186 return false;
5187 }
5188
5189 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5190 multislice.mslice_mode=control.value;
5191
5192 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
5193 control.value = resynchMarkerSpacingBytes;
5194 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5195
5196 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5197
5198 if (rc) {
5199 DEBUG_PRINT_ERROR("Failed to set MAX MB control");
5200 return false;
5201 }
5202
5203 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5204 multislice.mslice_mode = multislice_cfg.mslice_mode;
5205 multislice.mslice_size = multislice_cfg.mslice_size;
5206 return status;
5207 }
5208
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)5209 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
5210 {
5211 int rc;
5212 struct v4l2_control control;
5213 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
5214
5215 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
5216 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
5217 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
5218 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
5219 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
5220 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
5221 }
5222
5223 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5224 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5225
5226 if (rc) {
5227 return false;
5228 }
5229
5230 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5231
5232 dbkfilter.db_mode=control.value;
5233
5234 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
5235 control.value=0;
5236
5237 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5238 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5239
5240 if (rc) {
5241 return false;
5242 }
5243
5244 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5245 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
5246 control.value=0;
5247 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5248 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5249
5250 if (rc) {
5251 return false;
5252 }
5253
5254 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5255
5256
5257 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
5258 return true;
5259 }
5260
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)5261 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
5262 {
5263 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
5264 (unsigned int)nTargetBitrate);
5265 struct v4l2_control control;
5266 int rc = 0;
5267 control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
5268 control.value = nTargetBitrate;
5269
5270 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5271 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5272
5273 if (rc) {
5274 DEBUG_PRINT_ERROR("Failed to set control");
5275 return false;
5276 }
5277
5278 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5279
5280
5281 m_sVenc_cfg.targetbitrate = control.value;
5282 bitrate.target_bitrate = control.value;
5283
5284 if (!config) {
5285 m_level_set = false;
5286
5287 if (venc_set_profile_level(0, 0)) {
5288 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
5289 }
5290 }
5291
5292 // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
5293 // has been specified
5294 if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
5295 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
5296 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5297
5298 DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
5299 for (OMX_U32 i = 0; i < numLayers; ++i) {
5300 layerBitrates[i] =
5301 (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
5302 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
5303 i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
5304 layerBitrates[i], bitrate.target_bitrate);
5305 }
5306 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
5307 return false;
5308 }
5309 }
5310
5311 return true;
5312 }
5313
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)5314 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
5315 {
5316 struct v4l2_streamparm parm;
5317 int rc = 0;
5318 struct venc_framerate frame_rate_cfg;
5319 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
5320 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5321 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
5322 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
5323
5324 if (frame_rate_cfg.fps_numerator > 0)
5325 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
5326
5327 if (rc) {
5328 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
5329 return false;
5330 }
5331
5332 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
5333 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
5334
5335 if (!config) {
5336 m_level_set = false;
5337
5338 if (venc_set_profile_level(0, 0)) {
5339 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
5340 }
5341 }
5342
5343 return true;
5344 }
5345
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)5346 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
5347 {
5348 struct v4l2_format fmt;
5349 int color_space = 0;
5350 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
5351
5352 switch ((int)color_format) {
5353 case OMX_COLOR_FormatYUV420SemiPlanar:
5354 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
5355 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
5356 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5357 break;
5358 case QOMX_COLOR_FormatYVU420SemiPlanar:
5359 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
5360 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5361 break;
5362 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
5363 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
5364 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5365 break;
5366 case QOMX_COLOR_Format32bitRGBA8888:
5367 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
5368 break;
5369 case QOMX_COLOR_Format32bitRGBA8888Compressed:
5370 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
5371 break;
5372 default:
5373 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
5374 m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
5375 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
5376 DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
5377 break;
5378 }
5379
5380 memset(&fmt, 0, sizeof(fmt));
5381 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5382 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
5383 fmt.fmt.pix_mp.colorspace = color_space;
5384 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
5385 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
5386
5387 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5388 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
5389 return false;
5390 }
5391
5392 return true;
5393 }
5394
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)5395 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
5396 {
5397 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
5398
5399 if (intra_vop_refresh == OMX_TRUE) {
5400 struct v4l2_control control;
5401 int rc;
5402 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
5403 control.value = 1;
5404 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5405 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5406
5407 if (rc) {
5408 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
5409 return false;
5410 }
5411
5412 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5413 } else {
5414 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
5415 }
5416
5417 return true;
5418 }
5419
venc_set_deinterlace(OMX_U32 enable)5420 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
5421 {
5422 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
5423 struct v4l2_control control;
5424 int rc;
5425 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
5426 if (enable)
5427 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5428 else
5429 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
5430
5431 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5432 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5433 if (rc) {
5434 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
5435 return false;
5436 }
5437 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5438 deinterlace_enabled = true;
5439 return true;
5440 }
5441
venc_calibrate_gop()5442 bool venc_dev::venc_calibrate_gop()
5443 {
5444 int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
5445 int num_sub_gops_in_a_gop;
5446 nPframes = intra_period.num_pframes;
5447 nBframes = intra_period.num_bframes;
5448 nLayers = hier_layers.numlayers;
5449 if (temporal_layers_config.nPLayers) {
5450 nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
5451 }
5452
5453 if (!nPframes && nLayers) {
5454 DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
5455 return false;
5456 }
5457
5458 if (nLayers > 1) { /*Multi-layer encoding*/
5459 sub_gop_size = 1 << (nLayers - 1);
5460 /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
5461 * below calculations we are ignoring +1 . Ignoring +1 in below
5462 * calculations is not a mistake but intentional.
5463 */
5464 gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
5465 num_sub_gops_in_a_gop = gop_size/sub_gop_size;
5466 if (nBframes) { /*Hier-B case*/
5467 /*
5468 * Frame Type--> I B B B P B B B P I B B P ...
5469 * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ...
5470 * nPframes = 2, nBframes = 6, nLayers = 3
5471 *
5472 * Intention is to keep the intraperiod as close as possible to what is desired
5473 * by the client while adjusting nPframes and nBframes to meet other constraints.
5474 * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2
5475 * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
5476 *
5477 * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
5478 * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
5479 */
5480 nPframes = num_sub_gops_in_a_gop;
5481 nBframes = gop_size - nPframes;
5482 } else { /*Hier-P case*/
5483 /*
5484 * Frame Type--> I P P P P P P P I P P P P ...
5485 * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ...
5486 * nPframes = 7, nBframes = 0, nLayers = 3
5487 *
5488 * Intention is to keep the intraperiod as close as possible to what is desired
5489 * by the client while adjusting nPframes and nBframes to meet other constraints.
5490 * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
5491 * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
5492 *
5493 * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
5494 * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
5495 */
5496 nPframes = gop_size - 1;
5497 }
5498 } else { /*Single-layer encoding*/
5499 if (nBframes) {
5500 /* I P B B B P B B B P B B B I P B B...
5501 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...
5502 * nPframes = 3, nBframes = 9, nLayers = 0
5503 *
5504 * ratio is rounded,
5505 * eg1: nPframes = 9, nBframes = 11 => ratio = 1
5506 * eg2: nPframes = 9, nBframes = 16 => ratio = 2
5507 */
5508 ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
5509 nBframes = ratio * nPframes;
5510 }
5511 }
5512 DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
5513 intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
5514 intra_period.num_pframes = nPframes;
5515 intra_period.num_bframes = nBframes;
5516 hier_layers.numlayers = nLayers;
5517 return true;
5518 }
5519
venc_set_bitrate_type(OMX_U32 type)5520 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
5521 {
5522 struct v4l2_control control;
5523 int rc = 0;
5524 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
5525 control.value = type;
5526 DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
5527 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5528 if (rc) {
5529 DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
5530 bitrate_type_string(type));
5531 return false;
5532 }
5533 return true;
5534 }
5535
venc_set_layer_bitrates(OMX_U32 * layerBitrate,OMX_U32 numLayers)5536 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
5537 {
5538 DEBUG_PRINT_LOW("venc_set_layer_bitrates");
5539 struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
5540 struct v4l2_ext_controls controls;
5541 int rc = 0;
5542 OMX_U32 i;
5543
5544 if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
5545 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
5546 return false;
5547 }
5548
5549 for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
5550 if (!layerBitrate[i]) {
5551 DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
5552 return false;
5553 } else {
5554 ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
5555 ctrl[i].value = layerBitrate[i];
5556 }
5557 }
5558 controls.count = numLayers;
5559 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5560 controls.controls = ctrl;
5561
5562 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5563 if (rc) {
5564 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
5565 return false;
5566 }
5567
5568 DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
5569 return true;
5570 }
5571
venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE * hhp)5572 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
5573 {
5574 DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
5575 struct v4l2_control control;
5576 int rc;
5577
5578 if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
5579 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5580 return false;
5581 }
5582
5583 if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
5584 DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
5585 return false;
5586 }
5587 if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
5588 DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
5589 return false;
5590 }
5591
5592 hier_layers.numlayers = hhp->nHpLayers;
5593 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5594 hier_layers.hier_mode = HIER_P_HYBRID;
5595 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5596 hier_layers.hier_mode = HIER_P;
5597 }
5598 if (venc_calibrate_gop()) {
5599 // Update the driver with the new nPframes and nBframes
5600 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
5601 control.value = intra_period.num_pframes;
5602 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5603 if (rc) {
5604 DEBUG_PRINT_ERROR("Failed to set control");
5605 return false;
5606 }
5607
5608 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
5609 control.value = intra_period.num_bframes;
5610 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5611 if (rc) {
5612 DEBUG_PRINT_ERROR("Failed to set control");
5613 return false;
5614 }
5615 DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
5616 intra_period.num_pframes, intra_period.num_bframes);
5617 } else {
5618 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
5619 return false;
5620 }
5621 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5622 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
5623 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5624 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
5625 }
5626 control.value = hhp->nHpLayers - 1;
5627
5628 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
5629 control.id, control.value);
5630
5631 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5632 if (rc) {
5633 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
5634 return false;
5635 }
5636
5637 DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
5638 control.id, control.value);
5639 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5640 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
5641 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
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 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5647 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
5648 control.value = hhp->nHpLayers - 1;
5649 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
5650 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
5651 return false;
5652 }
5653 } else {
5654 DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
5655 return false;
5656 }
5657
5658 if(venc_set_session_qp_range (hhp->nMinQuantizer,
5659 hhp->nMaxQuantizer) == false) {
5660 DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
5661 (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
5662 return false;
5663 } else {
5664 session_qp_values.minqp = hhp->nMinQuantizer;
5665 session_qp_values.maxqp = hhp->nMaxQuantizer;
5666 }
5667
5668 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
5669 for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
5670 layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
5671 hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
5672 DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
5673 }
5674 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
5675 DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
5676 hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
5677 hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
5678 hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
5679 return false;
5680 }
5681 hybrid_hp.nHpLayers = hhp->nHpLayers;
5682
5683 // Set this or else the layer0 bitrate will be overwritten by
5684 // default value in component
5685 m_sVenc_cfg.targetbitrate = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
5686 hybrid_hp.nHpLayers = hhp->nHpLayers;
5687 hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
5688 hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
5689 hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
5690 return true;
5691 }
5692
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)5693 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
5694 {
5695 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
5696 struct v4l2_ext_control ctrl[2];
5697 struct v4l2_ext_controls controls;
5698 int rc;
5699
5700 if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
5701 DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
5702 return false;
5703 }
5704
5705 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
5706 if (enable)
5707 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
5708 else
5709 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
5710
5711 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
5712 if (enable && count > 0)
5713 ctrl[1].value = count;
5714 else if (enable)
5715 ctrl[1].value = 1;
5716 else
5717 ctrl[1].value = 0;
5718
5719 controls.count = 2;
5720 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5721 controls.controls = ctrl;
5722
5723 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
5724 controls.controls[0].id, controls.controls[0].value,
5725 controls.controls[1].id, controls.controls[1].value);
5726
5727 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5728 if (rc) {
5729 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5730 return false;
5731 }
5732 ltrinfo.enabled = enable;
5733 ltrinfo.count = count;
5734
5735 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
5736 controls.controls[0].id, controls.controls[0].value,
5737 controls.controls[1].id, controls.controls[1].value);
5738
5739 if (!venc_set_profile_level(0, 0)) {
5740 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
5741 __func__);
5742 } else {
5743 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
5744 __func__, codec_profile.profile, profile_level.level);
5745 }
5746
5747 return true;
5748 }
5749
venc_set_useltr(OMX_U32 frameIdx)5750 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
5751 {
5752 DEBUG_PRINT_LOW("venc_use_goldenframe");
5753 int rc = true;
5754 struct v4l2_control control;
5755
5756 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
5757 control.value = frameIdx;
5758
5759 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5760 if (rc) {
5761 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
5762 return false;
5763 }
5764
5765 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5766 control.id, control.value);
5767 return true;
5768 }
5769
venc_set_markltr(OMX_U32 frameIdx)5770 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
5771 {
5772 DEBUG_PRINT_LOW("venc_set_goldenframe");
5773 int rc = true;
5774 struct v4l2_control control;
5775
5776 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
5777 control.value = frameIdx;
5778
5779 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5780 if (rc) {
5781 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
5782 return false;
5783 }
5784
5785 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
5786 control.id, control.value);
5787 return true;
5788 }
5789
venc_set_vpe_rotation(OMX_S32 rotation_angle)5790 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
5791 {
5792 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
5793 struct v4l2_control control;
5794 int rc;
5795 struct v4l2_format fmt;
5796 struct v4l2_requestbuffers bufreq;
5797
5798 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
5799 if (rotation_angle == 0)
5800 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
5801 else if (rotation_angle == 90)
5802 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
5803 else if (rotation_angle == 180)
5804 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
5805 else if (rotation_angle == 270)
5806 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
5807 else {
5808 DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
5809 return false;
5810 }
5811
5812 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
5813 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5814 if (rc) {
5815 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
5816 return false;
5817 }
5818 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
5819
5820 memset(&fmt, 0, sizeof(fmt));
5821 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5822 if (rotation_angle == 90 || rotation_angle == 270) {
5823 OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
5824 OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
5825 m_sVenc_cfg.dvs_height = nHeight;
5826 m_sVenc_cfg.dvs_width = nWidth;
5827 DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
5828 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
5829 }
5830
5831 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
5832 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
5833 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
5834 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
5835 DEBUG_PRINT_ERROR("Failed to set format on capture port");
5836 return false;
5837 }
5838
5839 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
5840 bufreq.memory = V4L2_MEMORY_USERPTR;
5841 bufreq.count = m_sOutput_buff_property.actualcount;
5842 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5843 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
5844 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
5845 return false;
5846 }
5847 if (bufreq.count >= m_sOutput_buff_property.mincount)
5848 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
5849
5850 return true;
5851 }
5852
venc_set_searchrange()5853 bool venc_dev::venc_set_searchrange()
5854 {
5855 DEBUG_PRINT_LOW("venc_set_searchrange");
5856 struct v4l2_control control;
5857 struct v4l2_ext_control ctrl[6];
5858 struct v4l2_ext_controls controls;
5859 int rc;
5860
5861 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5862 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5863 ctrl[0].value = 16;
5864 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5865 ctrl[1].value = 4;
5866 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5867 ctrl[2].value = 16;
5868 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5869 ctrl[3].value = 4;
5870 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5871 ctrl[4].value = 12;
5872 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5873 ctrl[5].value = 4;
5874 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
5875 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
5876 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5877 ctrl[0].value = 16;
5878 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5879 ctrl[1].value = 4;
5880 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5881 ctrl[2].value = 16;
5882 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5883 ctrl[3].value = 4;
5884 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5885 ctrl[4].value = 12;
5886 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5887 ctrl[5].value = 4;
5888 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5889 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
5890 ctrl[0].value = 4;
5891 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
5892 ctrl[1].value = 4;
5893 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
5894 ctrl[2].value = 4;
5895 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
5896 ctrl[3].value = 4;
5897 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
5898 ctrl[4].value = 4;
5899 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
5900 ctrl[5].value = 4;
5901 } else {
5902 DEBUG_PRINT_ERROR("Invalid codec type");
5903 return false;
5904 }
5905 controls.count = 6;
5906 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
5907 controls.controls = ctrl;
5908
5909 DEBUG_PRINT_LOW(" Calling IOCTL set control for"
5910 "id=%x, val=%d id=%x, val=%d"
5911 "id=%x, val=%d id=%x, val=%d"
5912 "id=%x, val=%d id=%x, val=%d",
5913 controls.controls[0].id, controls.controls[0].value,
5914 controls.controls[1].id, controls.controls[1].value,
5915 controls.controls[2].id, controls.controls[2].value,
5916 controls.controls[3].id, controls.controls[3].value,
5917 controls.controls[4].id, controls.controls[4].value,
5918 controls.controls[5].id, controls.controls[5].value);
5919
5920 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
5921 if (rc) {
5922 DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
5923 return false;
5924 }
5925 return true;
5926 }
5927
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)5928 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
5929 {
5930 bool status = true;
5931 struct v4l2_control control;
5932 int rc = 0;
5933 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
5934
5935 switch (eControlRate) {
5936 case OMX_Video_ControlRateDisable:
5937 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
5938 break;
5939 case OMX_Video_ControlRateVariableSkipFrames:
5940 (supported_rc_modes & RC_VBR_VFR) ?
5941 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
5942 status = false;
5943 break;
5944 case OMX_Video_ControlRateVariable:
5945 (supported_rc_modes & RC_VBR_CFR) ?
5946 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
5947 status = false;
5948 break;
5949 case OMX_Video_ControlRateConstantSkipFrames:
5950 (supported_rc_modes & RC_CBR_VFR) ?
5951 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
5952 status = false;
5953 break;
5954 case OMX_Video_ControlRateConstant:
5955 (supported_rc_modes & RC_CBR_CFR) ?
5956 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
5957 status = false;
5958 break;
5959 default:
5960 status = false;
5961 break;
5962 }
5963
5964 if (status) {
5965
5966 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
5967 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
5968
5969 if (rc) {
5970 DEBUG_PRINT_ERROR("Failed to set control");
5971 return false;
5972 }
5973
5974 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
5975
5976 rate_ctrl.rcmode = control.value;
5977 }
5978
5979 #ifdef _VQZIP_
5980 if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
5981 && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5982 /* Enable VQZIP SEI by default for camcorder RC modes */
5983
5984 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
5985 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
5986 DEBUG_PRINT_HIGH("Set VQZIP SEI:");
5987 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
5988 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
5989 }
5990 }
5991 #endif //_VQZIP_
5992
5993 return status;
5994 }
5995
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)5996 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
5997 {
5998 bool status = true;
5999 struct v4l2_control control;
6000 int rc = 0;
6001 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
6002
6003 switch (ePerfLevel) {
6004 case OMX_QCOM_PerfLevelNominal:
6005 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
6006 break;
6007 case OMX_QCOM_PerfLevelTurbo:
6008 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
6009 break;
6010 default:
6011 status = false;
6012 break;
6013 }
6014
6015 if (status) {
6016 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6017 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6018
6019 if (rc) {
6020 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
6021 return false;
6022 }
6023
6024 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6025 }
6026 return status;
6027 }
6028
venc_set_perf_mode(OMX_U32 mode)6029 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
6030 {
6031 struct v4l2_control control;
6032 if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
6033 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
6034 control.value = mode;
6035 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6036 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6037 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
6038 return false;
6039 }
6040 return true;
6041 } else {
6042 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
6043 return false;
6044 }
6045 }
6046
venc_set_qp(OMX_U32 nQp)6047 bool venc_dev::venc_set_qp(OMX_U32 nQp)
6048 {
6049 struct v4l2_control control;
6050 if (nQp) {
6051 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
6052 control.value = nQp;
6053 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6054 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6055 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
6056 return false;
6057 }
6058 } else {
6059 DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
6060 return false;
6061 }
6062 return true;
6063 }
6064
venc_set_aspectratio(void * nSar)6065 bool venc_dev::venc_set_aspectratio(void *nSar)
6066 {
6067 int rc;
6068 struct v4l2_control control;
6069 struct v4l2_ext_control ctrl[2];
6070 struct v4l2_ext_controls controls;
6071 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
6072
6073 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
6074
6075 ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
6076 ctrl[0].value = sar->nSARWidth;
6077 ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
6078 ctrl[1].value = sar->nSARHeight;
6079
6080 controls.count = 2;
6081 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
6082 controls.controls = ctrl;
6083
6084 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
6085 controls.controls[0].id, controls.controls[0].value,
6086 controls.controls[1].id, controls.controls[1].value);
6087
6088 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
6089 if (rc) {
6090 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
6091 return false;
6092 }
6093
6094 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
6095 controls.controls[0].id, controls.controls[0].value,
6096 controls.controls[1].id, controls.controls[1].value);
6097 return true;
6098 }
6099
venc_set_hierp_layers(OMX_U32 hierp_layers)6100 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
6101 {
6102 struct v4l2_control control;
6103 if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
6104 (hierp_layers <= hier_layers.numlayers)) {
6105 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6106 control.value = hierp_layers - 1;
6107 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
6108 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6109 DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
6110 return false;
6111 }
6112 return true;
6113 } else {
6114 DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
6115 hierp_layers);
6116 return false;
6117 }
6118 }
6119
venc_set_baselayerid(OMX_U32 baseid)6120 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
6121 {
6122 struct v4l2_control control;
6123 if (hier_layers.hier_mode == HIER_P) {
6124 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
6125 control.value = baseid;
6126 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6127 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6128 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
6129 return false;
6130 }
6131 return true;
6132 } else {
6133 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
6134 hier_layers.hier_mode);
6135 return false;
6136 }
6137 }
6138
venc_set_vui_timing_info(OMX_BOOL enable)6139 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
6140 {
6141 struct v4l2_control control;
6142 int rc = 0;
6143 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
6144
6145 if (enable)
6146 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
6147 else
6148 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
6149
6150 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
6151 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6152 if (rc) {
6153 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
6154 return false;
6155 }
6156 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
6157 return true;
6158 }
6159
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)6160 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
6161 {
6162 struct v4l2_control control;
6163 int rc = 0;
6164 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
6165 control.value = nPeakBitrate;
6166
6167 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
6168
6169 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6170 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6171
6172 if (rc) {
6173 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
6174 return false;
6175 }
6176
6177 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6178
6179 return true;
6180 }
6181
venc_set_vpx_error_resilience(OMX_BOOL enable)6182 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
6183 {
6184 struct v4l2_control control;
6185 int rc = 0;
6186 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
6187
6188 if (enable)
6189 control.value = 1;
6190 else
6191 control.value = 0;
6192
6193 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
6194
6195 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6196
6197 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
6198 if (rc) {
6199 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
6200 return false;
6201 }
6202 vpx_err_resilience.enable = 1;
6203 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
6204 return true;
6205 }
6206
venc_set_priority(OMX_U32 priority)6207 bool venc_dev::venc_set_priority(OMX_U32 priority) {
6208 struct v4l2_control control;
6209
6210 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
6211 if (priority == 0)
6212 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
6213 else
6214 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
6215
6216 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6217 DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
6218 priority == 0 ? "ENABLE" : "DISABLE");
6219 return false;
6220 }
6221 return true;
6222 }
6223
venc_set_operatingrate(OMX_U32 rate)6224 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
6225 struct v4l2_control control;
6226
6227 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
6228 control.value = rate;
6229
6230 DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
6231 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
6232
6233 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6234 hw_overload = errno == EBUSY;
6235 DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
6236 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
6237 return false;
6238 }
6239 operating_rate = rate;
6240 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16);
6241 return true;
6242 }
6243
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)6244 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
6245 char *userptr;
6246 int fd;
6247 unsigned offset;
6248 ssize_t size;
6249 struct msm_vidc_roi_qp_payload *roiData;
6250 if (!roiInfo) {
6251 DEBUG_PRINT_ERROR("No ROI info present");
6252 return false;
6253 }
6254 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
6255 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
6256 DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
6257 return false;
6258 }
6259
6260 venc_roiqp_log_buffers(roiInfo);
6261 mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
6262 if (!userptr || size < roiInfo->nRoiMBInfoSize) {
6263 DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
6264 return false;
6265 }
6266
6267 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
6268 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
6269 data->nVersion.nVersion = OMX_SPEC_VERSION;
6270 data->nPortIndex = 0;
6271 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
6272 data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
6273
6274 roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
6275 roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
6276 roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
6277 roiData->b_roi_info = roiInfo->bUseRoiInfo;
6278 roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
6279 memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
6280
6281 data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
6282 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
6283 data->nVersion.nVersion = OMX_SPEC_VERSION;
6284 data->nPortIndex = 0;
6285 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
6286 data->nDataSize = 0;
6287 return true;
6288 }
6289
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)6290 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
6291 OMX_U32 *nMaxBLayers) {
6292
6293 // no B-layers for all cases
6294 temporal_layers_config.nMaxBLayers = 0;
6295 temporal_layers_config.nMaxLayers = 1;
6296
6297 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6298 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6299 temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
6300 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6301 temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
6302 }
6303
6304 *nMaxLayers = temporal_layers_config.nMaxLayers;
6305 *nMaxBLayers = temporal_layers_config.nMaxBLayers;
6306 return true;
6307 }
6308
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)6309 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
6310 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
6311
6312 if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
6313 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
6314 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
6315 DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
6316 return OMX_ErrorUnsupportedSetting;
6317 }
6318
6319 if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
6320 (pTemporalParams->nBLayerCountActual != 0 ||
6321 pTemporalParams->nPLayerCountActual != 1)) {
6322 return OMX_ErrorBadParameter;
6323 } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
6324 pTemporalParams->nPLayerCountActual < 1) {
6325 return OMX_ErrorBadParameter;
6326 }
6327
6328 if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
6329 DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
6330 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
6331 return OMX_ErrorBadParameter;
6332 } else if (pTemporalParams->nPLayerCountActual >
6333 temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
6334 DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
6335 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
6336 temporal_layers_config.nMaxLayers);
6337 return OMX_ErrorBadParameter;
6338 }
6339
6340 // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
6341 // use hybrid-HP for best results
6342 bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
6343 bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
6344 bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
6345
6346 // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
6347 bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
6348
6349 DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
6350 rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
6351
6352 if (bUseHybridMode &&
6353 !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
6354 pTemporalParams->nBLayerCountActual,
6355 0 /* LTR count */, (int) HIER_P_HYBRID)) {
6356 bUseHybridMode = false;
6357 DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
6358 }
6359
6360 if (intra_period.num_bframes) {
6361 DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
6362 return OMX_ErrorUnsupportedSetting;
6363 }
6364
6365 if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
6366 DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
6367 intra_period.num_pframes, intra_period.num_bframes);
6368 return OMX_ErrorUnsupportedSetting;
6369 }
6370
6371 struct v4l2_control control;
6372 // Num enhancements layers does not include the base-layer
6373 control.value = pTemporalParams->nPLayerCountActual - 1;
6374
6375 if (bUseHybridMode) {
6376 DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
6377 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6378 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6379 bUseHybridMode = false;
6380 DEBUG_PRINT_ERROR("Failed to set hybrid HP");
6381 } else {
6382 // Disable normal HP if Hybrid mode is being enabled
6383 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6384 control.value = 0;
6385 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6386 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6387 return OMX_ErrorUnsupportedSetting;
6388 }
6389 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6390 control.value = 0;
6391 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6392 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
6393 return OMX_ErrorUnsupportedSetting;
6394 }
6395 }
6396 }
6397
6398 if (!bUseHybridMode) {
6399
6400 // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
6401 if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
6402 DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
6403 return OMX_ErrorUnsupportedSetting;
6404 }
6405
6406 DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
6407 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
6408 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6409 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
6410 return OMX_ErrorUnsupportedSetting;
6411 }
6412
6413 // configure max layers for a session.. Okay to use current num-layers as max
6414 // since we do not plan to support dynamic changes to number of layers
6415 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
6416 control.value = pTemporalParams->nPLayerCountActual - 1;
6417 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6418 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
6419 return OMX_ErrorUnsupportedSetting;
6420
6421 } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
6422 // Disable hybrid mode if it was enabled already
6423 DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
6424 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
6425 control.value = 0;
6426 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6427 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
6428 return OMX_ErrorUnsupportedSetting;
6429 }
6430 }
6431 }
6432
6433 // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
6434 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6435 DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
6436 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
6437 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
6438 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
6439 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
6440 return OMX_ErrorUnsupportedSetting;
6441 }
6442 }
6443
6444 temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
6445 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
6446 temporal_layers_config.nBLayers = 0;
6447
6448 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
6449 if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
6450 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
6451 return OMX_ErrorNone;
6452 }
6453 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
6454
6455 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
6456 numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
6457
6458 OMX_U32 i = 0;
6459 for (; i < numLayers; ++i) {
6460 OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
6461 OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
6462 if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
6463 DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
6464 return OMX_ErrorBadParameter;
6465 } else {
6466 layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
6467 temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
6468 temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
6469 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
6470 i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
6471 }
6472 }
6473
6474 temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
6475
6476 // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
6477 if (bitrate.target_bitrate > 0) {
6478 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
6479 return OMX_ErrorUnsupportedSetting;
6480 }
6481 } else {
6482 DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
6483 }
6484
6485 return OMX_ErrorNone;
6486 }
6487
venc_set_temporal_layers_internal()6488 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
6489 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
6490 memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
6491
6492 if (!temporal_layers_config.nPLayers) {
6493 return OMX_ErrorNone;
6494 }
6495 pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6496 pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
6497 pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
6498 pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
6499 pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
6500 pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
6501 pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
6502 if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
6503 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
6504 pTemporalParams.nBitrateRatios[i] =
6505 temporal_layers_config.nTemporalLayerBitrateRatio[i];
6506 }
6507 }
6508 return venc_set_temporal_layers(&pTemporalParams);
6509 }
6510
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6511 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
6512 {
6513 bool status = true;
6514
6515 if (eProfile == NULL || eLevel == NULL) {
6516 return false;
6517 }
6518
6519 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6520 switch (codec_profile.profile) {
6521 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6522 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6523 break;
6524 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6525 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6526 break;
6527 default:
6528 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
6529 status = false;
6530 break;
6531 }
6532
6533 if (!status) {
6534 return status;
6535 }
6536
6537 //profile level
6538 switch (profile_level.level) {
6539 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
6540 *eLevel = OMX_VIDEO_MPEG4Level0;
6541 break;
6542 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
6543 *eLevel = OMX_VIDEO_MPEG4Level0b;
6544 break;
6545 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
6546 *eLevel = OMX_VIDEO_MPEG4Level1;
6547 break;
6548 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
6549 *eLevel = OMX_VIDEO_MPEG4Level2;
6550 break;
6551 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
6552 *eLevel = OMX_VIDEO_MPEG4Level3;
6553 break;
6554 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
6555 *eLevel = OMX_VIDEO_MPEG4Level4;
6556 break;
6557 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
6558 *eLevel = OMX_VIDEO_MPEG4Level5;
6559 break;
6560 default:
6561 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6562 status = false;
6563 break;
6564 }
6565 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6566 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
6567 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6568 } else {
6569 *eProfile = OMX_VIDEO_H263ProfileMax;
6570 return false;
6571 }
6572
6573 switch (profile_level.level) {
6574 case VEN_LEVEL_H263_10:
6575 *eLevel = OMX_VIDEO_H263Level10;
6576 break;
6577 case VEN_LEVEL_H263_20:
6578 *eLevel = OMX_VIDEO_H263Level20;
6579 break;
6580 case VEN_LEVEL_H263_30:
6581 *eLevel = OMX_VIDEO_H263Level30;
6582 break;
6583 case VEN_LEVEL_H263_40:
6584 *eLevel = OMX_VIDEO_H263Level40;
6585 break;
6586 case VEN_LEVEL_H263_45:
6587 *eLevel = OMX_VIDEO_H263Level45;
6588 break;
6589 case VEN_LEVEL_H263_50:
6590 *eLevel = OMX_VIDEO_H263Level50;
6591 break;
6592 case VEN_LEVEL_H263_60:
6593 *eLevel = OMX_VIDEO_H263Level60;
6594 break;
6595 case VEN_LEVEL_H263_70:
6596 *eLevel = OMX_VIDEO_H263Level70;
6597 break;
6598 default:
6599 *eLevel = OMX_VIDEO_H263LevelMax;
6600 status = false;
6601 break;
6602 }
6603 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6604 switch (codec_profile.profile) {
6605 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6606 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6607 break;
6608 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6609 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6610 break;
6611 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6612 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6613 break;
6614 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6615 *eProfile = OMX_VIDEO_AVCProfileMain;
6616 break;
6617 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6618 *eProfile = OMX_VIDEO_AVCProfileHigh;
6619 break;
6620 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6621 *eProfile = OMX_VIDEO_AVCProfileExtended;
6622 break;
6623 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6624 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6625 break;
6626 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6627 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6628 break;
6629 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6630 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6631 break;
6632 default:
6633 *eProfile = OMX_VIDEO_AVCProfileMax;
6634 status = false;
6635 break;
6636 }
6637
6638 if (!status) {
6639 return status;
6640 }
6641
6642 switch (profile_level.level) {
6643 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
6644 *eLevel = OMX_VIDEO_AVCLevel1;
6645 break;
6646 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
6647 *eLevel = OMX_VIDEO_AVCLevel1b;
6648 break;
6649 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
6650 *eLevel = OMX_VIDEO_AVCLevel11;
6651 break;
6652 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
6653 *eLevel = OMX_VIDEO_AVCLevel12;
6654 break;
6655 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
6656 *eLevel = OMX_VIDEO_AVCLevel13;
6657 break;
6658 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
6659 *eLevel = OMX_VIDEO_AVCLevel2;
6660 break;
6661 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
6662 *eLevel = OMX_VIDEO_AVCLevel21;
6663 break;
6664 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
6665 *eLevel = OMX_VIDEO_AVCLevel22;
6666 break;
6667 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
6668 *eLevel = OMX_VIDEO_AVCLevel3;
6669 break;
6670 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
6671 *eLevel = OMX_VIDEO_AVCLevel31;
6672 break;
6673 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
6674 *eLevel = OMX_VIDEO_AVCLevel32;
6675 break;
6676 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
6677 *eLevel = OMX_VIDEO_AVCLevel4;
6678 break;
6679 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
6680 *eLevel = OMX_VIDEO_AVCLevel41;
6681 break;
6682 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
6683 *eLevel = OMX_VIDEO_AVCLevel42;
6684 break;
6685 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
6686 *eLevel = OMX_VIDEO_AVCLevel5;
6687 break;
6688 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
6689 *eLevel = OMX_VIDEO_AVCLevel51;
6690 break;
6691 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
6692 *eLevel = OMX_VIDEO_AVCLevel52;
6693 break;
6694 default :
6695 *eLevel = OMX_VIDEO_AVCLevelMax;
6696 status = false;
6697 break;
6698 }
6699 }
6700 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6701 switch (codec_profile.profile) {
6702 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6703 *eProfile = OMX_VIDEO_VP8ProfileMain;
6704 break;
6705 default:
6706 *eProfile = OMX_VIDEO_VP8ProfileMax;
6707 status = false;
6708 break;
6709 }
6710 if (!status) {
6711 return status;
6712 }
6713
6714 switch (profile_level.level) {
6715 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6716 *eLevel = OMX_VIDEO_VP8Level_Version0;
6717 break;
6718 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6719 *eLevel = OMX_VIDEO_VP8Level_Version1;
6720 break;
6721 default:
6722 *eLevel = OMX_VIDEO_VP8LevelMax;
6723 status = false;
6724 break;
6725 }
6726 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6727 switch (codec_profile.profile) {
6728 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6729 *eProfile = OMX_VIDEO_HEVCProfileMain;
6730 break;
6731 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6732 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6733 break;
6734 default:
6735 *eProfile = OMX_VIDEO_HEVCProfileMax;
6736 status = false;
6737 break;
6738 }
6739 if (!status) {
6740 return status;
6741 }
6742
6743 switch (profile_level.level) {
6744 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
6745 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
6746 break;
6747 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
6748 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
6749 break;
6750 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
6751 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
6752 break;
6753 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
6754 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
6755 break;
6756 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
6757 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
6758 break;
6759 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
6760 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
6761 break;
6762 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
6763 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
6764 break;
6765 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
6766 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
6767 break;
6768 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
6769 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
6770 break;
6771 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
6772 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
6773 break;
6774 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
6775 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
6776 break;
6777 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
6778 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
6779 break;
6780 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
6781 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
6782 break;
6783 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
6784 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
6785 break;
6786 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
6787 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
6788 break;
6789 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
6790 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
6791 break;
6792 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
6793 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
6794 break;
6795 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
6796 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
6797 break;
6798 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
6799 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
6800 break;
6801 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
6802 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
6803 break;
6804 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
6805 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
6806 break;
6807 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
6808 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
6809 break;
6810 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
6811 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
6812 break;
6813 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
6814 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
6815 break;
6816 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
6817 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
6818 break;
6819 default:
6820 *eLevel = OMX_VIDEO_HEVCLevelMax;
6821 status = false;
6822 break;
6823 }
6824 }
6825
6826 return status;
6827 }
6828
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)6829 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
6830 {
6831 OMX_U32 new_profile = 0, new_level = 0;
6832 unsigned const int *profile_tbl = NULL;
6833 OMX_U32 mb_per_frame, mb_per_sec;
6834 bool profile_level_found = false;
6835
6836 DEBUG_PRINT_LOW("Init profile table for respective codec");
6837
6838 //validate the ht,width,fps,bitrate and set the appropriate profile and level
6839 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
6840 if (*eProfile == 0) {
6841 if (!m_profile_set) {
6842 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6843 } else {
6844 switch (codec_profile.profile) {
6845 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
6846 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
6847 break;
6848 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
6849 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
6850 break;
6851 default:
6852 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6853 return false;
6854 }
6855 }
6856 }
6857
6858 if (*eLevel == 0 && !m_level_set) {
6859 *eLevel = OMX_VIDEO_MPEG4LevelMax;
6860 }
6861
6862 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
6863 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
6864 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
6865 profile_tbl = (unsigned int const *)
6866 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
6867 } else {
6868 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
6869 return false;
6870 }
6871 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
6872 if (*eProfile == 0) {
6873 if (!m_profile_set) {
6874 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6875 } else {
6876 switch (codec_profile.profile) {
6877 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
6878 *eProfile = OMX_VIDEO_AVCProfileBaseline;
6879 break;
6880 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
6881 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
6882 break;
6883 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
6884 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
6885 break;
6886 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
6887 *eProfile = OMX_VIDEO_AVCProfileMain;
6888 break;
6889 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
6890 *eProfile = OMX_VIDEO_AVCProfileExtended;
6891 break;
6892 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
6893 *eProfile = OMX_VIDEO_AVCProfileHigh;
6894 break;
6895 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
6896 *eProfile = OMX_VIDEO_AVCProfileHigh10;
6897 break;
6898 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
6899 *eProfile = OMX_VIDEO_AVCProfileHigh422;
6900 break;
6901 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
6902 *eProfile = OMX_VIDEO_AVCProfileHigh444;
6903 break;
6904 default:
6905 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6906 return false;
6907 }
6908 }
6909 }
6910
6911 if (*eLevel == 0 && !m_level_set) {
6912 *eLevel = OMX_VIDEO_AVCLevelMax;
6913 }
6914
6915 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
6916 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
6917 profile_tbl = (unsigned int const *)h264_profile_level_table;
6918 } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
6919 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
6920 profile_tbl = (unsigned int const *)
6921 (&h264_profile_level_table[H264_HP_START]);
6922 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
6923 profile_tbl = (unsigned int const *)
6924 (&h264_profile_level_table[H264_MP_START]);
6925 } else {
6926 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
6927 return false;
6928 }
6929 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
6930 if (*eProfile == 0) {
6931 if (!m_profile_set) {
6932 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6933 } else {
6934 switch (codec_profile.profile) {
6935 case VEN_PROFILE_H263_BASELINE:
6936 *eProfile = OMX_VIDEO_H263ProfileBaseline;
6937 break;
6938 default:
6939 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
6940 return false;
6941 }
6942 }
6943 }
6944
6945 if (*eLevel == 0 && !m_level_set) {
6946 *eLevel = OMX_VIDEO_H263LevelMax;
6947 }
6948
6949 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
6950 profile_tbl = (unsigned int const *)h263_profile_level_table;
6951 } else {
6952 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
6953 return false;
6954 }
6955 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
6956 if (*eProfile == 0) {
6957 *eProfile = OMX_VIDEO_VP8ProfileMain;
6958 } else {
6959 switch (codec_profile.profile) {
6960 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
6961 *eProfile = OMX_VIDEO_VP8ProfileMain;
6962 break;
6963 default:
6964 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
6965 return false;
6966 }
6967 }
6968 if (*eLevel == 0) {
6969 switch (profile_level.level) {
6970 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
6971 *eLevel = OMX_VIDEO_VP8Level_Version0;
6972 break;
6973 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
6974 *eLevel = OMX_VIDEO_VP8Level_Version1;
6975 break;
6976 default:
6977 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
6978 return false;
6979 }
6980 }
6981 return true;
6982 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
6983 if (*eProfile == 0) {
6984 if (!m_profile_set) {
6985 *eProfile = OMX_VIDEO_HEVCProfileMain;
6986 } else {
6987 switch (codec_profile.profile) {
6988 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
6989 *eProfile = OMX_VIDEO_HEVCProfileMain;
6990 break;
6991 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
6992 *eProfile = OMX_VIDEO_HEVCProfileMain10;
6993 break;
6994 default:
6995 DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
6996 return false;
6997 }
6998 }
6999 }
7000
7001 if (*eLevel == 0 && !m_level_set) {
7002 *eLevel = OMX_VIDEO_HEVCLevelMax;
7003 }
7004
7005 if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
7006 profile_tbl = (unsigned int const *)hevc_profile_level_table;
7007 } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
7008 profile_tbl = (unsigned int const *)
7009 (&hevc_profile_level_table[HEVC_MAIN10_START]);
7010 } else {
7011 DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
7012 return false;
7013 }
7014 } else {
7015 DEBUG_PRINT_ERROR("Invalid codec type");
7016 return false;
7017 }
7018
7019 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
7020 ((m_sVenc_cfg.dvs_width + 15)>> 4);
7021
7022 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
7023 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
7024 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7025
7026 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
7027 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
7028
7029 {
7030 new_level = profile_level.level;
7031 new_profile = codec_profile.profile;
7032 return true;
7033 }
7034 }
7035
7036 if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
7037 *eLevel = rc_off_level; //No level calculation for RC_OFF
7038 profile_level_found = true;
7039 return true;
7040 }
7041
7042 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
7043
7044 bool h264, ltr, hlayers;
7045 unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
7046 h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
7047 ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7048 hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
7049 ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
7050
7051 /* Hybrid HP reference buffers:
7052 layers = 1, 2 need 1 reference buffer
7053 layers = 3, 4 need 2 reference buffers
7054 layers = 5, 6 need 3 reference buffers
7055 */
7056
7057 if(hier_layers.hier_mode == HIER_P_HYBRID)
7058 hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
7059
7060 do {
7061 if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
7062 if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
7063 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
7064 if (h264 && (ltr || hlayers || hybridp)) {
7065 // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
7066 new_level = (int)profile_tbl[3];
7067 new_profile = (int)profile_tbl[4];
7068 profile_level_found = true;
7069 DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
7070 ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
7071 MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
7072 break;
7073 } else {
7074 new_level = (int)profile_tbl[3];
7075 new_profile = (int)profile_tbl[4];
7076 profile_level_found = true;
7077 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
7078 break;
7079 }
7080 }
7081 }
7082 }
7083 profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
7084 } while (profile_tbl[0] != 0);
7085
7086 if (profile_level_found != true) {
7087 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
7088 return false;
7089 }
7090
7091 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
7092 || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
7093 || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
7094 *eLevel = new_level;
7095 }
7096
7097 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
7098 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
7099
7100 return true;
7101 }
7102 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)7103 bool venc_dev::venc_set_meta_mode(bool mode)
7104 {
7105 metadatamode = mode;
7106 return true;
7107 }
7108 #endif
7109
venc_is_video_session_supported(unsigned long width,unsigned long height)7110 bool venc_dev::venc_is_video_session_supported(unsigned long width,
7111 unsigned long height)
7112 {
7113 if ((width * height < capability.min_width * capability.min_height) ||
7114 (width * height > capability.max_width * capability.max_height)) {
7115 DEBUG_PRINT_ERROR(
7116 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
7117 width, height, capability.min_width, capability.min_height,
7118 capability.max_width, capability.max_height);
7119 return false;
7120 }
7121
7122 DEBUG_PRINT_LOW("video session supported");
7123 return true;
7124 }
7125
venc_set_batch_size(OMX_U32 batchSize)7126 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
7127 {
7128 struct v4l2_control control;
7129 int ret;
7130
7131 control.id = V4L2_CID_VIDC_QBUF_MODE;
7132 control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
7133
7134 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
7135 if (ret) {
7136 DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
7137 return false;
7138 }
7139
7140 mBatchSize = batchSize;
7141 DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
7142 return true;
7143 }
7144
BatchInfo()7145 venc_dev::BatchInfo::BatchInfo()
7146 : mNumPending(0) {
7147 pthread_mutex_init(&mLock, NULL);
7148 for (int i = 0; i < kMaxBufs; ++i) {
7149 mBufMap[i] = kBufIDFree;
7150 }
7151 }
7152
registerBuffer(int bufferId)7153 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
7154 pthread_mutex_lock(&mLock);
7155 int availId = 0;
7156 for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
7157 if (availId >= kMaxBufs) {
7158 DEBUG_PRINT_ERROR("Failed to find free entry !");
7159 pthread_mutex_unlock(&mLock);
7160 return -1;
7161 }
7162 mBufMap[availId] = bufferId;
7163 mNumPending++;
7164 pthread_mutex_unlock(&mLock);
7165 return availId;
7166 }
7167
retrieveBufferAt(int v4l2Id)7168 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
7169 pthread_mutex_lock(&mLock);
7170 if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
7171 DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
7172 pthread_mutex_unlock(&mLock);
7173 return -1;
7174 }
7175 if (mBufMap[v4l2Id] == kBufIDFree) {
7176 DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
7177 pthread_mutex_unlock(&mLock);
7178 return -1;
7179 }
7180 int bufferId = mBufMap[v4l2Id];
7181 mBufMap[v4l2Id] = kBufIDFree;
7182 mNumPending--;
7183 pthread_mutex_unlock(&mLock);
7184 return bufferId;
7185 }
7186
isPending(int bufferId)7187 bool venc_dev::BatchInfo::isPending(int bufferId) {
7188 pthread_mutex_lock(&mLock);
7189 int existsId = 0;
7190 for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
7191 pthread_mutex_unlock(&mLock);
7192 return existsId < kMaxBufs;
7193 }
7194
getFdAt(native_handle_t * hnd,int index)7195 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
7196 int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
7197 return fd;
7198 }
7199
getOffsetAt(native_handle_t * hnd,int index)7200 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
7201 int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
7202 return off;
7203 }
7204
getSizeAt(native_handle_t * hnd,int index)7205 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
7206 int size = hnd && (index + hnd->numFds) < hnd->numInts ?
7207 hnd->data[2*hnd->numFds + index] : -1;
7208 return size;
7209 }
7210
getColorFormatAt(native_handle_t * hnd,int index)7211 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
7212 int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
7213 hnd->data[3*hnd->numFds + index] : 0;
7214 return usage;
7215 }
7216
getTimeStampAt(native_handle_t * hnd,int index)7217 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
7218 int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
7219 hnd->data[4*hnd->numFds + index] : -1;
7220 return size;
7221 }
7222
7223 #ifdef _VQZIP_
venc_dev_vqzip()7224 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
7225 {
7226 mLibHandle = NULL;
7227 pthread_mutex_init(&lock, NULL);
7228 }
7229
init()7230 bool venc_dev::venc_dev_vqzip::init()
7231 {
7232 bool status = true;
7233 if (mLibHandle) {
7234 DEBUG_PRINT_ERROR("VQZIP init called twice");
7235 status = false;
7236 }
7237 if (status) {
7238 mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
7239 if (mLibHandle) {
7240 mVQZIPInit = (vqzip_init_t)
7241 dlsym(mLibHandle,"VQZipInit");
7242 mVQZIPDeInit = (vqzip_deinit_t)
7243 dlsym(mLibHandle,"VQZipDeInit");
7244 mVQZIPComputeStats = (vqzip_compute_stats_t)
7245 dlsym(mLibHandle,"VQZipComputeStats");
7246 if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
7247 status = false;
7248 } else {
7249 DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
7250 status = false;
7251 }
7252 if (status) {
7253 mVQZIPHandle = mVQZIPInit();
7254 }
7255 }
7256 if (!status && mLibHandle) {
7257 dlclose(mLibHandle);
7258 mLibHandle = NULL;
7259 mVQZIPHandle = NULL;
7260 mVQZIPInit = NULL;
7261 mVQZIPDeInit = NULL;
7262 mVQZIPComputeStats = NULL;
7263 }
7264 return status;
7265 }
7266
fill_stats_data(void * pBuf,void * extraData)7267 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
7268 {
7269 VQZipStatus result;
7270 VQZipStats *pStats = (VQZipStats *)extraData;
7271 pConfig.pSEIPayload = NULL;
7272 unsigned long size;
7273
7274 if (!pBuf || !pStats || !mVQZIPHandle) {
7275 DEBUG_PRINT_ERROR("Invalid data passed to stats function");
7276 }
7277 result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
7278 return (result < 0);
7279 }
7280
deinit()7281 void venc_dev::venc_dev_vqzip::deinit()
7282 {
7283 if (mLibHandle) {
7284 pthread_mutex_lock(&lock);
7285 dlclose(mLibHandle);
7286 mVQZIPDeInit(mVQZIPHandle);
7287 mLibHandle = NULL;
7288 mVQZIPHandle = NULL;
7289 mVQZIPInit = NULL;
7290 mVQZIPDeInit = NULL;
7291 mVQZIPComputeStats = NULL;
7292 pthread_mutex_unlock(&lock);
7293 }
7294 }
7295
~venc_dev_vqzip()7296 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
7297 {
7298 DEBUG_PRINT_HIGH("Destroy C2D instance");
7299 if (mLibHandle) {
7300 dlclose(mLibHandle);
7301 }
7302 mLibHandle = NULL;
7303 pthread_mutex_destroy(&lock);
7304 }
7305 #endif
7306
encExtradata(class omx_venc * venc_handle)7307 encExtradata::encExtradata(class omx_venc *venc_handle)
7308 {
7309 mCount = 0;
7310 mSize = 0;
7311 mUaddr = NULL;
7312 memset(&mIon, -1, sizeof(struct venc_ion));
7313 memset(mIndex, 0, sizeof(mIndex));
7314 mVencHandle = venc_handle;
7315 mDbgEtbCount = 0;
7316 pthread_mutex_init(&lock, NULL);
7317 vqzip_sei_found = false;
7318 }
7319
~encExtradata()7320 encExtradata::~encExtradata()
7321 {
7322 __free();
7323 mCount = 0;
7324 mSize = 0;
7325 mVencHandle = NULL;
7326 pthread_mutex_destroy(&lock);
7327 }
7328
__allocate()7329 OMX_ERRORTYPE encExtradata::__allocate()
7330 {
7331 ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
7332 if (!mVencHandle) {
7333 return OMX_ErrorInsufficientResources;
7334 }
7335 if (mUaddr || !totalSize) {
7336 return OMX_ErrorNone;
7337 }
7338 mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
7339 totalSize,
7340 &mIon.ion_alloc_data,
7341 &mIon.fd_ion_data, 0);
7342 if (mIon.ion_device_fd < 0) {
7343 DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
7344 DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
7345 return OMX_ErrorInsufficientResources;
7346 }
7347 mUaddr = (char *)mmap(NULL, totalSize,
7348 PROT_READ|PROT_WRITE, MAP_SHARED,
7349 mIon.fd_ion_data.fd , 0);
7350 if (mUaddr == MAP_FAILED) {
7351 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
7352 close(mIon.fd_ion_data.fd);
7353 mVencHandle->free_ion_memory(&mIon);
7354 return OMX_ErrorInsufficientResources;
7355 }
7356 for (unsigned i = 0; i < mCount; i++) {
7357 mIndex[i].status = FREE;
7358 mIndex[i].cookie = NULL;
7359 }
7360 return OMX_ErrorNone;
7361 }
7362
__get(char ** userptr,int * fd,unsigned * offset,ssize_t * size,int type)7363 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
7364 {
7365 unsigned i = 0;
7366 if (__allocate() != OMX_ErrorNone) {
7367 return -1;
7368 }
7369 for (i = 0; i < mCount; i++) {
7370 if (mIndex[i].status == type) {
7371 mIndex[i].status = BUSY;
7372 break;
7373 }
7374 }
7375 if (i >= mCount) {
7376 DEBUG_PRINT_HIGH("No Free extradata available");
7377 return -1;
7378 }
7379 *userptr = mUaddr + i * mSize;
7380 *fd = mIon.fd_ion_data.fd;
7381 *offset = i * mSize;
7382 *size = mSize;
7383 return i;
7384 }
7385
get(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7386 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
7387 int index;
7388 *userptr = NULL;
7389 *fd = -1;
7390 *offset = 0;
7391 *size = 0;
7392 pthread_mutex_lock(&lock);
7393 index = __get(userptr, fd, offset, size, FREE);
7394 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7395 pthread_mutex_unlock(&lock);
7396 return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
7397 }
7398
get(void * cookie,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7399 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
7400 {
7401 OMX_ERRORTYPE rc = OMX_ErrorNone;
7402 unsigned int i;
7403 *userptr = NULL;
7404 *fd = -1;
7405 *offset = 0;
7406 *size = 0;
7407 pthread_mutex_lock(&lock);
7408 for (i = 0; i < mCount; i++) {
7409 if (mIndex[i].cookie == cookie) {
7410 break;
7411 }
7412 }
7413 if (i < mCount) {
7414 *userptr = mUaddr + i * mSize;
7415 *fd = mIon.fd_ion_data.fd;
7416 *offset = i * mSize;
7417 *size = mSize;
7418 } else {
7419 int index = __get(userptr, fd, offset, size, FREE);
7420 if (index < 0 ) {
7421 DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
7422 __debug();
7423 rc = OMX_ErrorInsufficientResources;
7424 }
7425 }
7426 DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
7427 pthread_mutex_unlock(&lock);
7428 return rc;
7429 }
7430
getForConfig(char ** userptr,int * fd,unsigned * offset,ssize_t * size)7431 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
7432 {
7433 OMX_ERRORTYPE rc = OMX_ErrorNone;
7434 unsigned int i;
7435 int found = -1;
7436 pthread_mutex_lock(&lock);
7437 found = __get(userptr, fd, offset, size, FOR_CONFIG);
7438 if (found < 0) {
7439 found = __get(userptr, fd, offset, size, FREE);
7440 }
7441
7442 if (found < 0) {
7443 DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
7444 __debug();
7445 rc = OMX_ErrorInsufficientResources;
7446 } else {
7447 mIndex[found].status = FOR_CONFIG;
7448 DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
7449 }
7450 pthread_mutex_unlock(&lock);
7451 return rc;
7452 }
7453
put(char * userptr)7454 OMX_ERRORTYPE encExtradata::put(char *userptr)
7455 {
7456 OMX_ERRORTYPE rc = OMX_ErrorNone;
7457 int index = (userptr - mUaddr)/mSize;
7458 pthread_mutex_lock(&lock);
7459 if (!userptr) {
7460 DEBUG_PRINT_HIGH("Userptr is NULL");
7461 rc = OMX_ErrorBadParameter;
7462 } else if (index < 0) {
7463 DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
7464 __debug();
7465 rc = OMX_ErrorBadParameter;
7466 } else {
7467 mIndex[index].status = FREE;
7468 mIndex[index].cookie = NULL;
7469 DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
7470 }
7471 pthread_mutex_unlock(&lock);
7472 return rc;
7473 }
7474
peek(unsigned index,char ** userptr,int * fd,unsigned * offset,ssize_t * size)7475 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
7476 {
7477 OMX_ERRORTYPE rc = OMX_ErrorNone;
7478 *userptr = 0;
7479 *fd = -1;
7480 *offset = 0;
7481 *size = 0;
7482 pthread_mutex_lock(&lock);
7483 if (index < mCount) {
7484 rc = __allocate();
7485 if (rc == OMX_ErrorNone) {
7486 *userptr = mUaddr + index * mSize;
7487 *fd = mIon.fd_ion_data.fd;
7488 *offset = index * mSize;
7489 *size = mSize;
7490 }
7491 }
7492 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
7493 pthread_mutex_unlock(&lock);
7494 return rc;
7495 }
7496
setCookieForConfig(void * cookie)7497 void encExtradata::setCookieForConfig(void *cookie)
7498 {
7499 char *userptr;
7500 int fd;
7501 unsigned offset;
7502 ssize_t size;
7503 pthread_mutex_lock(&lock);
7504 int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
7505 if (found >= 0) {
7506 mIndex[found].cookie = cookie;
7507 } else {
7508 DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
7509 found, cookie);
7510 __debug();
7511 }
7512 mDbgEtbCount++;
7513 pthread_mutex_unlock(&lock);
7514 }
7515
__free()7516 void encExtradata::__free()
7517 {
7518 ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
7519 if (mUaddr) {
7520 munmap((void *)mUaddr, totalSize);
7521 mUaddr = NULL;
7522 }
7523 if (mIon.fd_ion_data.fd >= 0) {
7524 if (mVencHandle)
7525 mVencHandle->free_ion_memory(&mIon);
7526 close(mIon.fd_ion_data.fd);
7527 mIon.fd_ion_data.fd = -1;
7528 }
7529 for (unsigned i = 0; i < mCount; i++) {
7530 mIndex[i].status = FREE;
7531 mIndex[i].cookie = NULL;
7532 }
7533 }
7534
update(unsigned int count,ssize_t size)7535 void encExtradata::update(unsigned int count, ssize_t size)
7536 {
7537 pthread_mutex_lock(&lock);
7538 __free();
7539 mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
7540 mSize = size;
7541 DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
7542 pthread_mutex_unlock(&lock);
7543 }
7544
__debug()7545 void encExtradata::__debug()
7546 {
7547 DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
7548 this, mCount, mSize, mUaddr, mVencHandle);
7549 for (unsigned i = 0; i < mCount; i++) {
7550 DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
7551 }
7552 }
7553
getBufferSize()7554 ssize_t encExtradata::getBufferSize()
7555 {
7556 return mSize;
7557 }
7558
getBufferCount()7559 unsigned int encExtradata::getBufferCount()
7560 {
7561 return mCount;
7562 }
7563