1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2015, 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 <unistd.h>
33 #include <fcntl.h>
34 #include "video_encoder_device_v4l2.h"
35 #include "omx_video_encoder.h"
36 #include <media/msm_vidc.h>
37 #ifdef USE_ION
38 #include <linux/msm_ion.h>
39 #endif
40 #include <media/msm_media_info.h>
41 #include <cutils/properties.h>
42 #include <media/hardware/HardwareAPI.h>
43
44 #ifdef _ANDROID_
45 #include <media/hardware/HardwareAPI.h>
46 #include <gralloc_priv.h>
47 #include <qdMetaData.h>
48 #endif
49
50 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
51 #define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
52 #define MAXDPB 16
53 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
54 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
55 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
56 #define MAX_PROFILE_PARAMS 6
57 #define MPEG4_SP_START 0
58 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
59 #define H263_BP_START 0
60 #define H264_BP_START 0
61 #define H264_HP_START (H264_BP_START + 17)
62 #define H264_MP_START (H264_BP_START + 34)
63 #define HEVC_MAIN_START 0
64 #define HEVC_MAIN10_START (HEVC_MAIN_START + 12)
65 #define POLL_TIMEOUT 1000
66 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
67
68 #define SZ_4K 0x1000
69 #define SZ_1M 0x100000
70
71 /* MPEG4 profile and level table*/
72 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
73 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
74 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
75 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
76 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
77 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
78 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
79 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
80 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
81 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
82 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
83 {0,0,0,0,0,0},
84
85 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
86 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
87 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
88 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
89 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
90 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
91 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
92 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
93 {0,0,0,0,0,0},
94 };
95
96 /* H264 profile and level table*/
97 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
98 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
99 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
100 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
101 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
102 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
103 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
104 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
105 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
106 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
107 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
108 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
109 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
110 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
111 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
112 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
113 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
114 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
115 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
116 {0,0,0,0,0,0},
117
118 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
119 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
120 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
121 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
122 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
123 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
124 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
125 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
126 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
127 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
128 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
129 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
130 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
131 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
132 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
133 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
134 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
135 {0,0,0,0,0,0},
136
137 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
138 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
139 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
140 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
141 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
142 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
143 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
144 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
145 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
146 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
147 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
148 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
149 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
150 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
151 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
152 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
153 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
154 {0,0,0,0,0,0}
155
156 };
157
158 /* H263 profile and level table*/
159 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
160 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
161 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
162 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
163 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
164 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
165 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
166 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
167 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
168 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
169 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
170 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
171 {0,0,0,0,0,0}
172 };
173
174 /* HEVC profile and level table*/
175 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
176 /*max mb per frame, max mb per sec, max bitrate, level, profile*/
177 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
178 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
179 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
180 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
181 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
182 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
183 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
184 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
185 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
186 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
187 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
188 {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
189 {0,0,0,0,0},
190
191 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
192 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
193 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
194 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
195 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
196 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
197 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
198 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
199 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
200 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
201 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
202 {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
203 {0,0,0,0,0},
204 };
205
206 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
207 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
208
209 #define BUFFER_LOG_LOC "/data/misc/media"
210
211 //constructor
venc_dev(class omx_venc * venc_class)212 venc_dev::venc_dev(class omx_venc *venc_class)
213 {
214 //nothing to do
215 int i = 0;
216 venc_handle = venc_class;
217 etb = ebd = ftb = fbd = 0;
218
219 for (i = 0; i < MAX_PORT; i++)
220 streaming[i] = false;
221
222 stopped = 1;
223 paused = false;
224 async_thread_created = false;
225 color_format = 0;
226 hw_overload = false;
227 pthread_mutex_init(&pause_resume_mlock, NULL);
228 pthread_cond_init(&pause_resume_cond, NULL);
229 memset(&extradata_info, 0, sizeof(extradata_info));
230 memset(&idrperiod, 0, sizeof(idrperiod));
231 memset(&multislice, 0, sizeof(multislice));
232 memset (&slice_mode, 0 , sizeof(slice_mode));
233 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
234 memset(&rate_ctrl, 0, sizeof(rate_ctrl));
235 memset(&bitrate, 0, sizeof(bitrate));
236 memset(&intra_period, 0, sizeof(intra_period));
237 memset(&codec_profile, 0, sizeof(codec_profile));
238 memset(&set_param, 0, sizeof(set_param));
239 memset(&time_inc, 0, sizeof(time_inc));
240 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
241 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
242 memset(&session_qp, 0, sizeof(session_qp));
243 memset(&entropy, 0, sizeof(entropy));
244 memset(&dbkfilter, 0, sizeof(dbkfilter));
245 memset(&intra_refresh, 0, sizeof(intra_refresh));
246 memset(&hec, 0, sizeof(hec));
247 memset(&voptimecfg, 0, sizeof(voptimecfg));
248 memset(&capability, 0, sizeof(capability));
249 memset(&m_debug,0,sizeof(m_debug));
250 memset(&hier_layers,0,sizeof(hier_layers));
251 is_searchrange_set = false;
252 enable_mv_narrow_searchrange = false;
253 supported_rc_modes = RC_ALL;
254 camera_mode_enabled = false;
255 memset(<rinfo, 0, sizeof(ltrinfo));
256 sess_priority.priority = 1;
257 operating_rate = 0;
258 memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
259
260 char property_value[PROPERTY_VALUE_MAX] = {0};
261 property_get("vidc.enc.log.in", property_value, "0");
262 m_debug.in_buffer_log = atoi(property_value);
263
264 property_get("vidc.enc.log.out", property_value, "0");
265 m_debug.out_buffer_log = atoi(property_value);
266
267 property_get("vidc.enc.log.extradata", property_value, "0");
268 m_debug.extradata_log = atoi(property_value);
269
270 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
271 "%s", BUFFER_LOG_LOC);
272 }
273
~venc_dev()274 venc_dev::~venc_dev()
275 {
276 //nothing to do
277 }
278
async_venc_message_thread(void * input)279 void* venc_dev::async_venc_message_thread (void *input)
280 {
281 struct venc_msg venc_msg;
282 omx_video* omx_venc_base = NULL;
283 omx_venc *omx = reinterpret_cast<omx_venc*>(input);
284 omx_venc_base = reinterpret_cast<omx_video*>(input);
285 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
286
287 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
288 struct v4l2_plane plane[VIDEO_MAX_PLANES];
289 struct pollfd pfd;
290 struct v4l2_buffer v4l2_buf;
291 struct v4l2_event dqevent;
292 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
293 pfd.fd = omx->handle->m_nDriver_fd;
294 int error_code = 0,rc=0;
295
296 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
297
298 while (1) {
299 pthread_mutex_lock(&omx->handle->pause_resume_mlock);
300
301 if (omx->handle->paused) {
302 venc_msg.msgcode = VEN_MSG_PAUSE;
303 venc_msg.statuscode = VEN_S_SUCCESS;
304
305 if (omx->async_message_process(input, &venc_msg) < 0) {
306 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
307 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
308 break;
309 }
310
311 /* Block here until the IL client resumes us again */
312 pthread_cond_wait(&omx->handle->pause_resume_cond,
313 &omx->handle->pause_resume_mlock);
314
315 venc_msg.msgcode = VEN_MSG_RESUME;
316 venc_msg.statuscode = VEN_S_SUCCESS;
317
318 if (omx->async_message_process(input, &venc_msg) < 0) {
319 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
320 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
321 break;
322 }
323 }
324
325 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
326
327 rc = poll(&pfd, 1, POLL_TIMEOUT);
328
329 if (!rc) {
330 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
331 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
332 continue;
333 } else if (rc < 0) {
334 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
335 break;
336 }
337
338 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
339 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
340 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
341 v4l2_buf.length = omx->handle->num_planes;
342 v4l2_buf.m.planes = plane;
343
344 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
345 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
346 venc_msg.statuscode=VEN_S_SUCCESS;
347 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
348 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
349 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
350 venc_msg.buf.flags = 0;
351 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
352 venc_msg.buf.clientdata=(void*)omxhdr;
353 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
354
355 /* TODO: ideally report other types of frames as well
356 * for now it doesn't look like IL client cares about
357 * other types
358 */
359 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
360 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
361
362 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
363 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
364
365 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
366 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
367
368 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
369 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
370
371 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
372 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
373
374 if (omxhdr->nFilledLen)
375 venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
376
377 omx->handle->fbd++;
378
379 if (omx->async_message_process(input,&venc_msg) < 0) {
380 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
381 break;
382 }
383 }
384 }
385
386 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
387 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
388 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
389 v4l2_buf.m.planes = plane;
390 v4l2_buf.length = 1;
391
392 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
393 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
394 venc_msg.statuscode=VEN_S_SUCCESS;
395 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
396 omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
397 else
398 omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
399
400 venc_msg.buf.clientdata=(void*)omxhdr;
401 omx->handle->ebd++;
402
403 if (omx->async_message_process(input,&venc_msg) < 0) {
404 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
405 break;
406 }
407 }
408 }
409
410 if (pfd.revents & POLLPRI) {
411 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
412
413 if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
414 DEBUG_PRINT_HIGH("CLOSE DONE");
415 break;
416 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
417 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
418 venc_msg.statuscode = VEN_S_SUCCESS;
419
420 if (omx->async_message_process(input,&venc_msg) < 0) {
421 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
422 break;
423 }
424
425 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
426 venc_msg.statuscode = VEN_S_SUCCESS;
427
428 if (omx->async_message_process(input,&venc_msg) < 0) {
429 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
430 break;
431 }
432 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
433 DEBUG_PRINT_ERROR("HW Overload received");
434 venc_msg.statuscode = VEN_S_EFAIL;
435 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
436
437 if (omx->async_message_process(input,&venc_msg) < 0) {
438 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
439 break;
440 }
441 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
442 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
443 venc_msg.msgcode = VEN_MSG_INDICATION;
444 venc_msg.statuscode=VEN_S_EFAIL;
445
446 if (omx->async_message_process(input,&venc_msg) < 0) {
447 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
448 break;
449 }
450 }
451 }
452 }
453
454 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
455 return NULL;
456 }
457
458 static const int event_type[] = {
459 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
460 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
461 V4L2_EVENT_MSM_VIDC_SYS_ERROR
462 };
463
subscribe_to_events(int fd)464 static OMX_ERRORTYPE subscribe_to_events(int fd)
465 {
466 OMX_ERRORTYPE eRet = OMX_ErrorNone;
467 struct v4l2_event_subscription sub;
468 int array_sz = sizeof(event_type)/sizeof(int);
469 int i,rc;
470 memset(&sub, 0, sizeof(sub));
471
472 if (fd < 0) {
473 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
474 return OMX_ErrorBadParameter;
475 }
476
477 for (i = 0; i < array_sz; ++i) {
478 memset(&sub, 0, sizeof(sub));
479 sub.type = event_type[i];
480 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
481
482 if (rc) {
483 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
484 break;
485 }
486 }
487
488 if (i < array_sz) {
489 for (--i; i >=0 ; i--) {
490 memset(&sub, 0, sizeof(sub));
491 sub.type = event_type[i];
492 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
493
494 if (rc)
495 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
496 }
497
498 eRet = OMX_ErrorNotImplemented;
499 }
500
501 return eRet;
502 }
503
append_mbi_extradata(void * dst,struct msm_vidc_extradata_header * src)504 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
505 {
506 OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
507
508 if (!dst || !src)
509 return 0;
510
511 /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
512 * targets, since the payload format will be different */
513 mbi->nFormat = 1;
514 mbi->nDataSize = src->data_size;
515 memcpy(&mbi->data, &src->data, src->data_size);
516
517 return mbi->nDataSize + sizeof(*mbi);
518 }
519
handle_extradata(void * buffer,int index)520 bool venc_dev::handle_extradata(void *buffer, int index)
521 {
522 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
523 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
524
525 if (!extradata_info.uaddr) {
526 DEBUG_PRINT_ERROR("Extradata buffers not allocated");
527 return false;
528 }
529
530 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
531 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
532
533 if (extradata_info.buffer_size >
534 p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
535 DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
536 p_extra = NULL;
537 return false;
538 } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
539 /* A lot of the code below assumes this condition, so error out if it's not met */
540 DEBUG_PRINT_ERROR("Extradata ABI mismatch");
541 return false;
542 }
543
544 struct msm_vidc_extradata_header *p_extradata = NULL;
545 do {
546 p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
547 ((char *)p_extradata) + p_extradata->size :
548 extradata_info.uaddr + index * extradata_info.buffer_size);
549
550 switch (p_extradata->type) {
551 case MSM_VIDC_EXTRADATA_METADATA_MBI:
552 {
553 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
554 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
555 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
556 p_extra->nPortIndex = OMX_DirOutput;
557 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
558 p_extra->nDataSize = payloadSize;
559 break;
560 }
561 case MSM_VIDC_EXTRADATA_METADATA_LTR:
562 {
563 *p_extra->data = *p_extradata->data;
564 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
565 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
566 p_extra->nPortIndex = OMX_DirOutput;
567 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
568 p_extra->nDataSize = p_extradata->data_size;
569 break;
570 }
571 case MSM_VIDC_EXTRADATA_NONE:
572 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
573 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
574 p_extra->nPortIndex = OMX_DirOutput;
575 p_extra->eType = OMX_ExtraDataNone;
576 p_extra->nDataSize = 0;
577 break;
578 default:
579 /* No idea what this stuff is, just skip over it */
580 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
581 p_extradata->type);
582 continue;
583 }
584
585 p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
586 } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
587
588 /* Just for debugging: Traverse the list of extra datas and spit it out onto log */
589 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
590 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
591 while(p_extra->eType != OMX_ExtraDataNone)
592 {
593 DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
594 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
595 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
596
597 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
598 p_extra->nSize);
599 }
600
601 return true;
602 }
603
venc_set_format(int format)604 int venc_dev::venc_set_format(int format)
605 {
606 int rc = true;
607
608 if (format)
609 color_format = format;
610 else {
611 color_format = 0;
612 rc = false;
613 }
614
615 return rc;
616 }
617
allocate_extradata()618 OMX_ERRORTYPE venc_dev::allocate_extradata()
619 {
620 if (extradata_info.allocated) {
621 DEBUG_PRINT_ERROR("Extradata already allocated!");
622 return OMX_ErrorNone;
623 }
624
625 #ifdef USE_ION
626
627 if (extradata_info.buffer_size) {
628 if (extradata_info.ion.ion_alloc_data.handle) {
629 munmap((void *)extradata_info.uaddr, extradata_info.size);
630 close(extradata_info.ion.fd_ion_data.fd);
631 venc_handle->free_ion_memory(&extradata_info.ion);
632 }
633
634 extradata_info.size = ALIGN(extradata_info.size, SZ_4K);
635
636 extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory(
637 extradata_info.size,
638 &extradata_info.ion.ion_alloc_data,
639 &extradata_info.ion.fd_ion_data, 0);
640
641 if (extradata_info.ion.ion_device_fd < 0) {
642 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
643 return OMX_ErrorInsufficientResources;
644 }
645
646 extradata_info.uaddr = (char *)mmap(NULL,
647 extradata_info.size,
648 PROT_READ|PROT_WRITE, MAP_SHARED,
649 extradata_info.ion.fd_ion_data.fd , 0);
650
651 if (extradata_info.uaddr == MAP_FAILED) {
652 DEBUG_PRINT_ERROR("Failed to map extradata memory");
653 close(extradata_info.ion.fd_ion_data.fd);
654 venc_handle->free_ion_memory(&extradata_info.ion);
655 return OMX_ErrorInsufficientResources;
656 }
657 }
658
659 #endif
660 extradata_info.allocated = 1;
661 return OMX_ErrorNone;
662 }
663
free_extradata()664 void venc_dev::free_extradata()
665 {
666 #ifdef USE_ION
667
668 if (extradata_info.uaddr) {
669 munmap((void *)extradata_info.uaddr, extradata_info.size);
670 close(extradata_info.ion.fd_ion_data.fd);
671 venc_handle->free_ion_memory(&extradata_info.ion);
672 }
673
674 memset(&extradata_info, 0, sizeof(extradata_info));
675 #endif
676 }
677
venc_get_output_log_flag()678 bool venc_dev::venc_get_output_log_flag()
679 {
680 return (m_debug.out_buffer_log == 1);
681 }
682
venc_output_log_buffers(const char * buffer_addr,int buffer_len)683 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
684 {
685 if (venc_handle->is_secure_session()) {
686 DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
687 return -1;
688 }
689
690 if (!m_debug.outfile) {
691 int size = 0;
692 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
693 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
694 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
695 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
696 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
697 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
698 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
699 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
700 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
701 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
702 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
703 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
704 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
705 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
706 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
707 }
708 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
709 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
710 m_debug.outfile_name, size);
711 }
712 m_debug.outfile = fopen(m_debug.outfile_name, "ab");
713 if (!m_debug.outfile) {
714 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
715 m_debug.outfile_name, errno);
716 m_debug.outfile_name[0] = '\0';
717 return -1;
718 }
719 }
720 if (m_debug.outfile && buffer_len) {
721 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
722 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
723 }
724 return 0;
725 }
726
venc_extradata_log_buffers(char * buffer_addr)727 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
728 {
729 if (!m_debug.extradatafile && m_debug.extradata_log) {
730 int size = 0;
731 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
732 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
733 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
734 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
735 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
736 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
737 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
738 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
739 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
740 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
741 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
742 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
743 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
744 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
745 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
746 }
747 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
748 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
749 m_debug.extradatafile_name, size);
750 }
751
752 m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
753 if (!m_debug.extradatafile) {
754 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
755 m_debug.extradatafile_name, errno);
756 m_debug.extradatafile_name[0] = '\0';
757 return -1;
758 }
759 }
760
761 if (m_debug.extradatafile) {
762 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
763 do {
764 p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
765 ((char *)p_extra) + p_extra->nSize);
766 fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
767 } while (p_extra->eType != OMX_ExtraDataNone);
768 }
769 return 0;
770 }
771
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset)772 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) {
773 if (venc_handle->is_secure_session()) {
774 DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
775 return -1;
776 }
777
778 if (!m_debug.infile) {
779 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
780 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
781 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
782 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
783 m_debug.infile_name, size);
784 }
785 m_debug.infile = fopen (m_debug.infile_name, "ab");
786 if (!m_debug.infile) {
787 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
788 m_debug.infile_name[0] = '\0';
789 return -1;
790 }
791 }
792 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
793 unsigned long i, msize;
794 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
795 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
796 unsigned char *pvirt,*ptemp;
797
798 char *temp = (char *)pbuffer->pBuffer;
799
800 msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
801 if (metadatamode == 1) {
802 pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
803 if (pvirt) {
804 ptemp = pvirt;
805 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
806 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
807 ptemp += stride;
808 }
809 ptemp = pvirt + (stride * scanlines);
810 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
811 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
812 ptemp += stride;
813 }
814 munmap(pvirt, msize);
815 } else if (pvirt == MAP_FAILED) {
816 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
817 return -1;
818 }
819 } else {
820 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
821 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
822 temp += stride;
823 }
824
825 temp = (char *)pbuffer->pBuffer + (stride * scanlines);
826
827 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
828 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
829 temp += stride;
830 }
831 }
832 }
833 return 0;
834 }
835
venc_open(OMX_U32 codec)836 bool venc_dev::venc_open(OMX_U32 codec)
837 {
838 int r;
839 unsigned int alignment = 0,buffer_size = 0, temp =0;
840 struct v4l2_control control;
841 OMX_STRING device_name = (OMX_STRING)"/dev/video33";
842 char property_value[PROPERTY_VALUE_MAX] = {0};
843 char platform_name[PROPERTY_VALUE_MAX] = {0};
844
845 property_get("ro.board.platform", platform_name, "0");
846 property_get("vidc.enc.narrow.searchrange", property_value, "0");
847 enable_mv_narrow_searchrange = atoi(property_value);
848
849 if (!strncmp(platform_name, "msm8610", 7)) {
850 device_name = (OMX_STRING)"/dev/video/q6_enc";
851 supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
852 }
853 m_nDriver_fd = open (device_name, O_RDWR);
854
855 if (m_nDriver_fd == 0) {
856 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
857 m_nDriver_fd = open (device_name, O_RDWR);
858 }
859
860 if ((int)m_nDriver_fd < 0) {
861 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
862 return false;
863 }
864
865 DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
866 // set the basic configuration of the video encoder driver
867 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
868 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
869 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
870 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
871 m_sVenc_cfg.fps_num = 30;
872 m_sVenc_cfg.fps_den = 1;
873 m_sVenc_cfg.targetbitrate = 64000;
874 m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
875 m_codec = codec;
876
877 if (codec == OMX_VIDEO_CodingMPEG4) {
878 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
879 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
880 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
881 session_qp_range.minqp = 1;
882 session_qp_range.maxqp = 31;
883 } else if (codec == OMX_VIDEO_CodingH263) {
884 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
885 codec_profile.profile = VEN_PROFILE_H263_BASELINE;
886 profile_level.level = VEN_LEVEL_H263_20;
887 session_qp_range.minqp = 1;
888 session_qp_range.maxqp = 31;
889 } else if (codec == OMX_VIDEO_CodingAVC) {
890 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
891 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
892 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
893 session_qp_range.minqp = 1;
894 session_qp_range.maxqp = 51;
895 } else if (codec == OMX_VIDEO_CodingVP8) {
896 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
897 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
898 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
899 session_qp_range.minqp = 1;
900 session_qp_range.maxqp = 128;
901 } else if (codec == OMX_VIDEO_CodingHEVC) {
902 m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
903 session_qp_range.minqp = 1;
904 session_qp_range.maxqp = 51;
905 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
906 profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
907 }
908 session_qp_values.minqp = session_qp_range.minqp;
909 session_qp_values.maxqp = session_qp_range.maxqp;
910
911 int ret;
912 ret = subscribe_to_events(m_nDriver_fd);
913
914 if (ret) {
915 DEBUG_PRINT_ERROR("Subscribe Event Failed");
916 return false;
917 }
918
919 struct v4l2_capability cap;
920
921 struct v4l2_fmtdesc fdesc;
922
923 struct v4l2_format fmt;
924
925 struct v4l2_requestbuffers bufreq;
926
927 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
928
929 if (ret) {
930 DEBUG_PRINT_ERROR("Failed to query capabilities");
931 } else {
932 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
933 " version = %d, capabilities = %x", cap.driver, cap.card,
934 cap.bus_info, cap.version, cap.capabilities);
935 }
936
937 ret=0;
938 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
939 fdesc.index=0;
940
941 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
942 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
943 fdesc.pixelformat, fdesc.flags);
944 fdesc.index++;
945 }
946
947 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
948 fdesc.index=0;
949
950 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
951 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
952 fdesc.pixelformat, fdesc.flags);
953 fdesc.index++;
954 }
955
956 if (venc_handle->is_secure_session()) {
957 m_sOutput_buff_property.alignment = SZ_1M;
958 m_sInput_buff_property.alignment = SZ_1M;
959 } else {
960 m_sOutput_buff_property.alignment = SZ_4K;
961 m_sInput_buff_property.alignment = SZ_4K;
962 }
963 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
964 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
965 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
966 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
967
968 /*TODO: Return values not handled properly in this function anywhere.
969 * Need to handle those.*/
970 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
971
972 if (ret) {
973 DEBUG_PRINT_ERROR("Failed to set format on capture port");
974 return false;
975 }
976
977 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
978
979 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
980 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
981 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
982 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
983 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
984
985 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
986 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
987
988 bufreq.memory = V4L2_MEMORY_USERPTR;
989 bufreq.count = 2;
990
991 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
992 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
993 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
994
995 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
996 bufreq.count = 2;
997 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
998 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
999
1000 if(venc_handle->is_secure_session()) {
1001 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1002 control.value = 1;
1003 DEBUG_PRINT_HIGH("ioctl: open secure device");
1004 ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
1005 if (ret) {
1006 DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
1007 return false;
1008 }
1009 }
1010
1011 resume_in_stopped = 0;
1012 metadatamode = 0;
1013 camera_mode_enabled = false;
1014
1015 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
1016 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
1017
1018 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
1019
1020 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1021 DEBUG_PRINT_ERROR("Failed to set control");
1022
1023 struct v4l2_frmsizeenum frmsize;
1024
1025 //Get the hardware capabilities
1026 memset((void *)&frmsize,0,sizeof(frmsize));
1027 frmsize.index = 0;
1028 frmsize.pixel_format = m_sVenc_cfg.codectype;
1029 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1030
1031 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1032 DEBUG_PRINT_ERROR("Failed to get framesizes");
1033 return false;
1034 }
1035
1036 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1037 capability.min_width = frmsize.stepwise.min_width;
1038 capability.max_width = frmsize.stepwise.max_width;
1039 capability.min_height = frmsize.stepwise.min_height;
1040 capability.max_height = frmsize.stepwise.max_height;
1041 }
1042 //Initialize non-default parameters
1043 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1044 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
1045 control.value = 0x7fffffff;
1046 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1047 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
1048 }
1049
1050 property_get("vidc.debug.turbo", property_value, "0");
1051 if (atoi(property_value)) {
1052 DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
1053 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
1054 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
1055 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
1056 DEBUG_PRINT_ERROR("Failed to set turbo mode");
1057 }
1058 }
1059
1060 sess_priority.priority = 1; /* default to non-real-time */
1061 if (venc_set_session_priority(sess_priority.priority)) {
1062 DEBUG_PRINT_ERROR("Setting session priority failed");
1063 return OMX_ErrorUnsupportedSetting;
1064 }
1065 return true;
1066 }
1067
1068
unsubscribe_to_events(int fd)1069 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
1070 {
1071 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1072 struct v4l2_event_subscription sub;
1073 int array_sz = sizeof(event_type)/sizeof(int);
1074 int i,rc;
1075
1076 if (fd < 0) {
1077 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1078 return OMX_ErrorBadParameter;
1079 }
1080
1081 for (i = 0; i < array_sz; ++i) {
1082 memset(&sub, 0, sizeof(sub));
1083 sub.type = event_type[i];
1084 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1085
1086 if (rc) {
1087 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1088 break;
1089 }
1090 }
1091
1092 return eRet;
1093 }
1094
venc_close()1095 void venc_dev::venc_close()
1096 {
1097 struct v4l2_encoder_cmd enc;
1098 DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
1099
1100 if ((int)m_nDriver_fd >= 0) {
1101 enc.cmd = V4L2_ENC_CMD_STOP;
1102 ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
1103 DEBUG_PRINT_HIGH("venc_close E");
1104
1105 if (async_thread_created)
1106 pthread_join(m_tid,NULL);
1107
1108 DEBUG_PRINT_HIGH("venc_close X");
1109 unsubscribe_to_events(m_nDriver_fd);
1110 close(m_nDriver_fd);
1111 m_nDriver_fd = -1;
1112 }
1113
1114 if (m_debug.infile) {
1115 fclose(m_debug.infile);
1116 m_debug.infile = NULL;
1117 }
1118
1119 if (m_debug.outfile) {
1120 fclose(m_debug.outfile);
1121 m_debug.outfile = NULL;
1122 }
1123
1124 if (m_debug.extradatafile) {
1125 fclose(m_debug.extradatafile);
1126 m_debug.extradatafile = NULL;
1127 }
1128 }
1129
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1130 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1131 OMX_U32 *actual_buff_count,
1132 OMX_U32 *buff_size,
1133 OMX_U32 port)
1134 {
1135 (void)min_buff_count, (void)buff_size;
1136 unsigned long temp_count = 0;
1137
1138 if (port == 0) {
1139 if (*actual_buff_count > m_sInput_buff_property.mincount) {
1140 temp_count = m_sInput_buff_property.actualcount;
1141 m_sInput_buff_property.actualcount = *actual_buff_count;
1142 DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1143 }
1144 } else {
1145 if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1146 temp_count = m_sOutput_buff_property.actualcount;
1147 m_sOutput_buff_property.actualcount = *actual_buff_count;
1148 DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1149 }
1150 }
1151
1152 return true;
1153
1154 }
1155
venc_loaded_start()1156 bool venc_dev::venc_loaded_start()
1157 {
1158 return true;
1159 }
1160
venc_loaded_stop()1161 bool venc_dev::venc_loaded_stop()
1162 {
1163 return true;
1164 }
1165
venc_loaded_start_done()1166 bool venc_dev::venc_loaded_start_done()
1167 {
1168 return true;
1169 }
1170
venc_loaded_stop_done()1171 bool venc_dev::venc_loaded_stop_done()
1172 {
1173 return true;
1174 }
1175
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)1176 bool venc_dev::venc_get_seq_hdr(void *buffer,
1177 unsigned buffer_size, unsigned *header_len)
1178 {
1179 (void) buffer, (void) buffer_size, (void) header_len;
1180 return true;
1181 }
1182
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1183 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1184 OMX_U32 *actual_buff_count,
1185 OMX_U32 *buff_size,
1186 OMX_U32 port)
1187 {
1188 struct v4l2_format fmt;
1189 struct v4l2_requestbuffers bufreq;
1190 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1191 int ret;
1192
1193 if (port == 0) {
1194 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1195 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1196 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1197 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1198 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
1199 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1200 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1201 bufreq.memory = V4L2_MEMORY_USERPTR;
1202
1203 if (*actual_buff_count)
1204 bufreq.count = *actual_buff_count;
1205 else
1206 bufreq.count = 2;
1207
1208 // Increase buffer-header count for metadata-mode on input port
1209 // to improve buffering and reduce bottlenecks in clients
1210 if (metadatamode && (bufreq.count < 9)) {
1211 DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
1212 bufreq.count);
1213 bufreq.count = 9;
1214 }
1215 if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
1216 DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
1217 bufreq.count = 11;
1218 } else {
1219 bufreq.count = 12;
1220 }
1221
1222 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1223 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1224
1225 if (ret) {
1226 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1227 return false;
1228 }
1229
1230 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1231 *min_buff_count = m_sInput_buff_property.mincount;
1232 *actual_buff_count = m_sInput_buff_property.actualcount;
1233 #ifdef USE_ION
1234 // For ION memory allocations of the allocated buffer size
1235 // must be 4k aligned, hence aligning the input buffer
1236 // size to 4k.
1237 m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1238 #endif
1239 *buff_size = m_sInput_buff_property.datasize;
1240 } else {
1241 unsigned int extra_idx = 0;
1242 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1243 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1244 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1245 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1246
1247 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1248 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1249 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1250 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1251 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1252 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1253
1254 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1255 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1256 bufreq.memory = V4L2_MEMORY_USERPTR;
1257
1258 if (*actual_buff_count)
1259 bufreq.count = *actual_buff_count;
1260 else
1261 bufreq.count = 2;
1262
1263 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1264 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1265
1266 if (ret) {
1267 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1268 return false;
1269 }
1270
1271 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1272 *min_buff_count = m_sOutput_buff_property.mincount;
1273 *actual_buff_count = m_sOutput_buff_property.actualcount;
1274 *buff_size = m_sOutput_buff_property.datasize;
1275 num_planes = fmt.fmt.pix_mp.num_planes;
1276 extra_idx = EXTRADATA_IDX(num_planes);
1277
1278 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1279 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1280 } else if (extra_idx >= VIDEO_MAX_PLANES) {
1281 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1282 return OMX_ErrorBadParameter;
1283 }
1284
1285 extradata_info.buffer_size = extra_data_size;
1286 extradata_info.count = m_sOutput_buff_property.actualcount;
1287 extradata_info.size = extradata_info.buffer_size * extradata_info.count;
1288 }
1289
1290 return true;
1291 }
1292
venc_set_param(void * paramData,OMX_INDEXTYPE index)1293 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
1294 {
1295 DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1296 struct v4l2_format fmt;
1297 struct v4l2_requestbuffers bufreq;
1298 int ret;
1299
1300 switch ((int)index) {
1301 case OMX_IndexParamPortDefinition:
1302 {
1303 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1304 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1305 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1306
1307 if (portDefn->nPortIndex == PORT_INDEX_IN) {
1308 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1309 return false;
1310 }
1311
1312 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1313 return false;
1314 }
1315 if (enable_mv_narrow_searchrange &&
1316 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1317 (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1318 if (venc_set_searchrange() == false) {
1319 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1320 }
1321 }
1322 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1323 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1324 DEBUG_PRINT_LOW("Basic parameter has changed");
1325 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1326 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1327 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1328 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1329 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1330 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1331 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_BT878;
1332
1333 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1334 DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1335 hw_overload = errno == EBUSY;
1336 return false;
1337 }
1338
1339 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1340 bufreq.memory = V4L2_MEMORY_USERPTR;
1341 bufreq.count = portDefn->nBufferCountActual;
1342 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1343
1344 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1345 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1346 return false;
1347 }
1348
1349 if (bufreq.count == portDefn->nBufferCountActual)
1350 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1351
1352 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1353 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1354 }
1355
1356 DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1357 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1358 if (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >= 3840 * 2160) {
1359 if (venc_set_perf_mode(V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) == false) {
1360 DEBUG_PRINT_ERROR("ERROR: Failed to set Power save mode");
1361 }
1362 }
1363 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1364 m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1365 m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1366 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1367 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1368 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1369 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1370
1371 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1372 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1373 hw_overload = errno == EBUSY;
1374 return false;
1375 }
1376
1377 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1378
1379 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1380 return false;
1381 }
1382
1383 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1384 bufreq.memory = V4L2_MEMORY_USERPTR;
1385 bufreq.count = portDefn->nBufferCountActual;
1386 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1387
1388 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1389 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1390 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1391 return false;
1392 }
1393
1394 if (bufreq.count == portDefn->nBufferCountActual)
1395 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1396
1397 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1398 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1399
1400 if (num_planes > 1)
1401 extradata_info.count = m_sOutput_buff_property.actualcount;
1402
1403 DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1404 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1405 } else {
1406 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1407 }
1408
1409 break;
1410 }
1411 case OMX_IndexParamVideoPortFormat:
1412 {
1413 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1414 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1415 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1416
1417 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1418 if (!venc_set_color_format(portFmt->eColorFormat)) {
1419 return false;
1420 }
1421 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1422 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1423 return false;
1424 }
1425 } else {
1426 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1427 }
1428
1429 break;
1430 }
1431 case OMX_IndexParamVideoBitrate:
1432 {
1433 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1434 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1435 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1436
1437 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1438 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1439 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1440 return false;
1441 }
1442
1443 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1444 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1445 return false;
1446 }
1447 } else {
1448 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1449 }
1450
1451 break;
1452 }
1453 case OMX_IndexParamVideoMpeg4:
1454 {
1455 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1456 OMX_U32 bFrames = 0;
1457
1458 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1459 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1460
1461 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1462 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1463 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1464 return false;
1465 }
1466
1467 m_profile_set = false;
1468 m_level_set = false;
1469
1470 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1471 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1472 return false;
1473 } else {
1474 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1475 if (pParam->nBFrames) {
1476 bFrames = pParam->nBFrames;
1477 }
1478 } else {
1479 if (pParam->nBFrames) {
1480 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1481 bFrames = 0;
1482 }
1483 }
1484 }
1485
1486 if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
1487 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1488 return false;
1489 }
1490
1491 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1492 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1493 return false;
1494 }
1495 } else {
1496 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1497 }
1498
1499 break;
1500 }
1501 case OMX_IndexParamVideoH263:
1502 {
1503 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1504 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1505 OMX_U32 bFrames = 0;
1506
1507 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1508 m_profile_set = false;
1509 m_level_set = false;
1510
1511 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1512 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1513 return false;
1514 }
1515
1516 if (pParam->nBFrames)
1517 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1518
1519 if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
1520 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1521 return false;
1522 }
1523 } else {
1524 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1525 }
1526
1527 break;
1528 }
1529 case OMX_IndexParamVideoAvc:
1530 {
1531 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1532 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1533 OMX_U32 bFrames = 0;
1534
1535 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1536 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1537 pParam->eProfile,pParam->eLevel);
1538
1539 m_profile_set = false;
1540 m_level_set = false;
1541
1542 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1543 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1544 pParam->eProfile, pParam->eLevel);
1545 return false;
1546 } else {
1547 if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1548 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) OMX_VIDEO_AVCProfileConstrainedBaseline) &&
1549 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1550 if (pParam->nBFrames) {
1551 bFrames = pParam->nBFrames;
1552 }
1553 } else {
1554 if (pParam->nBFrames) {
1555 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1556 bFrames = 0;
1557 }
1558 }
1559 }
1560
1561 if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
1562 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1563 return false;
1564 }
1565
1566 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1567 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1568 return false;
1569 }
1570
1571 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1572 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1573 return false;
1574 }
1575
1576 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1577 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1578 return false;
1579 }
1580 } else {
1581 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1582 }
1583
1584 //TBD, lot of other variables to be updated, yet to decide
1585 break;
1586 }
1587 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1588 {
1589 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1590 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1591 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1592 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1593 pParam->eProfile, pParam->eLevel);
1594 return false;
1595 }
1596 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
1597 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
1598 return false;
1599 }
1600 if(!venc_set_ltrmode(1, 1)) {
1601 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1602 return false;
1603 }
1604
1605 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1606 // Disable hier-p if ltr is enabled.
1607 if (m_codec == OMX_VIDEO_CodingVP8) {
1608 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1609 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1610 DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1611 }
1612 }
1613
1614 break;
1615 }
1616 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1617 {
1618 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
1619 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1620 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1621 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1622 pParam->eProfile, pParam->eLevel);
1623 return false;
1624 }
1625 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
1626 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
1627
1628 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
1629 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
1630 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
1631 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1632 return false;
1633 }
1634 break;
1635 }
1636 case OMX_IndexParamVideoIntraRefresh:
1637 {
1638 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1639 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1640 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1641
1642 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1643 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1644 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1645 return false;
1646 }
1647 } else {
1648 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1649 }
1650
1651 break;
1652 }
1653 case OMX_IndexParamVideoErrorCorrection:
1654 {
1655 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1656 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1657 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1658
1659 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1660 if (venc_set_error_resilience(error_resilience) == false) {
1661 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1662 return false;
1663 }
1664 } else {
1665 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1666 }
1667
1668 break;
1669 }
1670 case OMX_IndexParamVideoProfileLevelCurrent:
1671 {
1672 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1673 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1674 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1675
1676 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1677 m_profile_set = false;
1678 m_level_set = false;
1679
1680 if (!venc_set_profile_level (profile_level->eProfile,
1681 profile_level->eLevel)) {
1682 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1683 return false;
1684 }
1685 } else {
1686 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1687 }
1688
1689 break;
1690 }
1691 case OMX_IndexParamVideoQuantization:
1692 {
1693 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
1694 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1695 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1696 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1697 if (venc_set_session_qp (session_qp->nQpI,
1698 session_qp->nQpP,
1699 session_qp->nQpB) == false) {
1700 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
1701 return false;
1702 }
1703 } else {
1704 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1705 }
1706
1707 break;
1708 }
1709 case QOMX_IndexParamVideoInitialQp:
1710 {
1711 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
1712 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
1713 if (initqp->bEnableInitQp) {
1714 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
1715 if(venc_enable_initial_qp(initqp) == false) {
1716 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
1717 return OMX_ErrorUnsupportedSetting;
1718 }
1719 } else
1720 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
1721 break;
1722 }
1723 case OMX_QcomIndexParamVideoQPRange:
1724 {
1725 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
1726 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
1727 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
1728
1729 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1730 if(venc_set_session_qp_range (session_qp_range->minQP,
1731 session_qp_range->maxQP) == false) {
1732 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
1733 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
1734 return false;
1735 } else {
1736 session_qp_values.minqp = session_qp_range->minQP;
1737 session_qp_values.maxqp = session_qp_range->maxQP;
1738 }
1739 } else {
1740 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1741 }
1742
1743 break;
1744 }
1745 case OMX_QcomIndexEnableSliceDeliveryMode:
1746 {
1747 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1748 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1749
1750 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1751 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1752 DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1753 return OMX_ErrorUnsupportedSetting;
1754 }
1755 } else {
1756 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1757 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
1758 return OMX_ErrorBadPortIndex;
1759 }
1760
1761 break;
1762 }
1763 case OMX_ExtraDataVideoEncoderSliceInfo:
1764 {
1765 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1766 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1767
1768 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
1769 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
1770 return false;
1771 }
1772
1773 extradata = true;
1774 break;
1775 }
1776 case OMX_ExtraDataVideoEncoderMBInfo:
1777 {
1778 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
1779 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1780
1781 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
1782 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
1783 return false;
1784 }
1785
1786 extradata = true;
1787 break;
1788 }
1789 case OMX_QcomIndexParamSequenceHeaderWithIDR:
1790 {
1791 PrependSPSPPSToIDRFramesParams * pParam =
1792 (PrependSPSPPSToIDRFramesParams *)paramData;
1793
1794 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
1795 if(venc_set_inband_video_header(pParam->bEnable) == false) {
1796 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
1797 return OMX_ErrorUnsupportedSetting;
1798 }
1799
1800 break;
1801 }
1802 case OMX_QcomIndexParamH264AUDelimiter:
1803 {
1804 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
1805 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
1806
1807 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
1808 if(venc_set_au_delimiter(pParam->bEnable) == false) {
1809 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
1810 return OMX_ErrorUnsupportedSetting;
1811 }
1812
1813 break;
1814 }
1815 case OMX_QcomIndexHierarchicalStructure:
1816 {
1817 QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
1818 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
1819
1820 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1821 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
1822 DEBUG_PRINT_ERROR("Setting Hier P count failed");
1823 return false;
1824 }
1825 } else {
1826 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
1827 return false;
1828 }
1829
1830 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1831 // Disable ltr if hier-p is enabled.
1832 if (m_codec == OMX_VIDEO_CodingVP8) {
1833 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
1834 if(!venc_set_ltrmode(0, 1)) {
1835 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
1836 }
1837 }
1838 break;
1839 }
1840 case OMX_QcomIndexParamPerfLevel:
1841 {
1842 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
1843 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
1844 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
1845 if(!venc_set_perf_level(pParam->ePerfLevel)) {
1846 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
1847 return false;
1848 } else {
1849 performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
1850 }
1851 break;
1852 }
1853 case OMX_QcomIndexParamH264VUITimingInfo:
1854 {
1855 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1856 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1857 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1858 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1859 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1860 return false;
1861 } else {
1862 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1863 }
1864 break;
1865 }
1866 case OMX_QcomIndexParamPeakBitrate:
1867 {
1868 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
1869 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
1870 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
1871 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
1872 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
1873 return false;
1874 } else {
1875 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
1876 }
1877 break;
1878 }
1879 case OMX_QcomIndexParamSetMVSearchrange:
1880 {
1881 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
1882 is_searchrange_set = true;
1883 if (!venc_set_searchrange()) {
1884 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1885 return false;
1886 }
1887 }
1888 break;
1889 case OMX_QcomIndexParamVideoLTRCount:
1890 {
1891 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
1892 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
1893 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
1894 if (pParam->nCount > 0) {
1895 if (venc_set_ltrmode(1, pParam->nCount) == false) {
1896 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
1897 return false;
1898 }
1899 } else {
1900 if (venc_set_ltrmode(0, 0) == false) {
1901 DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
1902 return false;
1903 }
1904 }
1905 break;
1906 }
1907 case OMX_QcomIndexParamVideoHybridHierpMode:
1908 {
1909 QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* pParam =
1910 (QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData;
1911
1912 if (!venc_set_hybrid_hierp(pParam->nHpLayers)) {
1913 DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
1914 return OMX_ErrorUnsupportedSetting;
1915 }
1916 break;
1917 }
1918 case OMX_IndexParamAndroidVideoTemporalLayering:
1919 {
1920 if (venc_set_temporal_layers(
1921 (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
1922 DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
1923 return false;
1924 }
1925 break;
1926 }
1927 case OMX_IndexParamVideoSliceFMO:
1928 default:
1929 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1930 index);
1931 break;
1932 //case
1933 }
1934
1935 return true;
1936 }
1937
venc_set_config(void * configData,OMX_INDEXTYPE index)1938 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1939 {
1940
1941 DEBUG_PRINT_LOW("Inside venc_set_config");
1942
1943 switch ((int)index) {
1944 case OMX_IndexConfigVideoBitrate:
1945 {
1946 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1947 configData;
1948 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
1949
1950 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1951 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1952 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
1953 return false;
1954 }
1955 } else {
1956 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1957 }
1958
1959 break;
1960 }
1961 case OMX_IndexConfigVideoFramerate:
1962 {
1963 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1964 configData;
1965 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
1966
1967 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1968 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1969 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1970 return false;
1971 }
1972 } else {
1973 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1974 }
1975
1976 break;
1977 }
1978 case QOMX_IndexConfigVideoIntraperiod:
1979 {
1980 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
1981 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1982 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1983
1984 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1985 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1986 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1987 return false;
1988 }
1989 }
1990
1991 break;
1992 }
1993 case OMX_IndexConfigVideoIntraVOPRefresh:
1994 {
1995 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1996 configData;
1997 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1998
1999 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2000 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
2001 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
2002 return false;
2003 }
2004 } else {
2005 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
2006 }
2007
2008 break;
2009 }
2010 case OMX_IndexConfigCommonRotate:
2011 {
2012 OMX_CONFIG_ROTATIONTYPE *config_rotation =
2013 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2014 OMX_U32 nFrameWidth;
2015 if (!config_rotation) {
2016 return false;
2017 }
2018 if (true == deinterlace_enabled) {
2019 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
2020 return false;
2021 }
2022 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
2023 nFrameWidth = m_sVenc_cfg.dvs_width;
2024 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height;
2025 m_sVenc_cfg.dvs_height = nFrameWidth;
2026
2027 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
2028 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
2029 return false;
2030 }
2031
2032 break;
2033 }
2034 case OMX_IndexConfigVideoAVCIntraPeriod:
2035 {
2036 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
2037 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
2038
2039 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
2040 == false) {
2041 DEBUG_PRINT_ERROR("ERROR: Setting "
2042 "OMX_IndexConfigVideoAVCIntraPeriod failed");
2043 return false;
2044 }
2045 break;
2046 }
2047 case OMX_IndexConfigCommonDeinterlace:
2048 {
2049 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
2050 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
2051 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
2052 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
2053 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
2054 {
2055 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
2056 return false;
2057 }
2058 if(venc_set_deinterlace(deinterlace->nEnable) == false) {
2059 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
2060 return false;
2061 }
2062 } else {
2063 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
2064 }
2065 break;
2066 }
2067 case OMX_IndexConfigVideoVp8ReferenceFrame:
2068 {
2069 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
2070 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2071 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2072 (vp8refframe->bUseGoldenFrame)) {
2073 if(venc_set_useltr(0x1) == false) {
2074 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
2075 return false;
2076 }
2077 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
2078 (vp8refframe->bGoldenFrameRefresh)) {
2079 if(venc_set_markltr(0x1) == false) {
2080 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
2081 return false;
2082 }
2083 } else {
2084 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
2085 }
2086 break;
2087 }
2088 case OMX_QcomIndexConfigVideoLTRUse:
2089 {
2090 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
2091 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
2092 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2093 if (venc_set_useltr(pParam->nID) == false) {
2094 DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
2095 return false;
2096 }
2097 } else {
2098 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
2099 }
2100 break;
2101 }
2102 case OMX_QcomIndexConfigVideoLTRMark:
2103 {
2104 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
2105 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
2106 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
2107 if (venc_set_markltr(pParam->nID) == false) {
2108 DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
2109 return false;
2110 }
2111 } else {
2112 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
2113 }
2114 break;
2115 }
2116 case OMX_QcomIndexConfigPerfLevel:
2117 {
2118 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
2119 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
2120 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
2121 if (!venc_set_perf_level(perf->ePerfLevel)) {
2122 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
2123 return false;
2124 } else {
2125 performance_level.perflevel = (unsigned int) perf->ePerfLevel;
2126 }
2127 break;
2128 }
2129 case OMX_QcomIndexConfigVideoVencPerfMode:
2130 {
2131 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
2132 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
2133 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
2134 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
2135 return false;
2136 }
2137 break;
2138 }
2139 case OMX_IndexConfigPriority:
2140 {
2141 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
2142 DEBUG_PRINT_LOW("Set_config: priority %u",priority->nU32);
2143 if (!venc_set_session_priority(priority->nU32)) {
2144 DEBUG_PRINT_ERROR("Failed to set priority");
2145 return false;
2146 }
2147 break;
2148 }
2149 case OMX_IndexConfigOperatingRate:
2150 {
2151 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
2152 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
2153 if (!venc_set_operatingrate(rate->nU32)) {
2154 DEBUG_PRINT_ERROR("Failed to set operating rate");
2155 return false;
2156 }
2157 break;
2158 }
2159 case OMX_IndexConfigAndroidIntraRefresh:
2160 {
2161 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
2162 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
2163
2164 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
2165 OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
2166 OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
2167
2168 if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
2169 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
2170 return false;
2171 }
2172 } else {
2173 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
2174 }
2175 break;
2176 }
2177 case OMX_IndexParamAndroidVideoTemporalLayering:
2178 {
2179 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
2180 return false;
2181 }
2182 default:
2183 DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
2184 break;
2185 }
2186
2187 return true;
2188 }
2189
venc_stop(void)2190 unsigned venc_dev::venc_stop( void)
2191 {
2192 struct venc_msg venc_msg;
2193 struct v4l2_requestbuffers bufreq;
2194 int rc = 0, ret = 0;
2195
2196 if (!stopped) {
2197 enum v4l2_buf_type cap_type;
2198
2199 if (streaming[OUTPUT_PORT]) {
2200 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2201 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2202
2203 if (rc) {
2204 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2205 cap_type, rc);
2206 } else
2207 streaming[OUTPUT_PORT] = false;
2208
2209 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2210 bufreq.memory = V4L2_MEMORY_USERPTR;
2211 bufreq.count = 0;
2212 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2213 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2214
2215 if (ret) {
2216 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2217 return false;
2218 }
2219 }
2220
2221 if (!rc && streaming[CAPTURE_PORT]) {
2222 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2223 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2224
2225 if (rc) {
2226 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2227 cap_type, rc);
2228 } else
2229 streaming[CAPTURE_PORT] = false;
2230
2231 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2232 bufreq.memory = V4L2_MEMORY_USERPTR;
2233 bufreq.count = 0;
2234 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2235 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2236
2237 if (ret) {
2238 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2239 return false;
2240 }
2241 }
2242
2243 if (!rc && !ret) {
2244 venc_stop_done();
2245 stopped = 1;
2246 /*set flag to re-configure when started again*/
2247 resume_in_stopped = 1;
2248
2249 }
2250 }
2251
2252 return rc;
2253 }
2254
venc_pause(void)2255 unsigned venc_dev::venc_pause(void)
2256 {
2257 pthread_mutex_lock(&pause_resume_mlock);
2258 paused = true;
2259 pthread_mutex_unlock(&pause_resume_mlock);
2260 return 0;
2261 }
2262
venc_resume(void)2263 unsigned venc_dev::venc_resume(void)
2264 {
2265 pthread_mutex_lock(&pause_resume_mlock);
2266 paused = false;
2267 pthread_mutex_unlock(&pause_resume_mlock);
2268
2269 return pthread_cond_signal(&pause_resume_cond);
2270 }
2271
venc_start_done(void)2272 unsigned venc_dev::venc_start_done(void)
2273 {
2274 struct venc_msg venc_msg;
2275 venc_msg.msgcode = VEN_MSG_START;
2276 venc_msg.statuscode = VEN_S_SUCCESS;
2277 venc_handle->async_message_process(venc_handle,&venc_msg);
2278 return 0;
2279 }
2280
venc_stop_done(void)2281 unsigned venc_dev::venc_stop_done(void)
2282 {
2283 struct venc_msg venc_msg;
2284 free_extradata();
2285 venc_msg.msgcode=VEN_MSG_STOP;
2286 venc_msg.statuscode=VEN_S_SUCCESS;
2287 venc_handle->async_message_process(venc_handle,&venc_msg);
2288 return 0;
2289 }
2290
venc_set_message_thread_id(pthread_t tid)2291 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2292 {
2293 async_thread_created = true;
2294 m_tid=tid;
2295 return 0;
2296 }
2297
2298
venc_start(void)2299 unsigned venc_dev::venc_start(void)
2300 {
2301 enum v4l2_buf_type buf_type;
2302 int ret, r;
2303 struct v4l2_control control;
2304
2305 memset(&control, 0, sizeof(control));
2306
2307 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2308 __func__);
2309 m_level_set = false;
2310
2311 if (!venc_set_profile_level(0, 0)) {
2312 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2313 __func__);
2314 } else {
2315 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2316 __func__, codec_profile.profile, profile_level.level);
2317 }
2318
2319 // re-configure the temporal layers as RC-mode and key-frame interval
2320 // might have changed since the client last configured the layers.
2321 if (temporal_layers_config.nPLayers) {
2322 if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
2323 DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
2324 } else {
2325 // request buffers on capture port again since internal (scratch)-
2326 // buffer requirements may change (i.e if we switch from non-hybrid
2327 // to hybrid mode and vice-versa)
2328 struct v4l2_requestbuffers bufreq;
2329
2330 bufreq.memory = V4L2_MEMORY_USERPTR;
2331 bufreq.count = m_sOutput_buff_property.actualcount;
2332 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2333 if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
2334 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
2335 }
2336 }
2337 }
2338
2339 venc_config_print();
2340
2341 if(resume_in_stopped){
2342 /*set buffercount when restarted*/
2343 venc_reconfig_reqbufs();
2344 resume_in_stopped = 0;
2345 }
2346
2347 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
2348 if (slice_mode.enable && multislice.mslice_size &&
2349 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
2350 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
2351 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
2352 MAX_SUPPORTED_SLICES_PER_FRAME);
2353 return 1;
2354 }
2355
2356 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2357 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2358 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
2359
2360 if (ret)
2361 return 1;
2362
2363 streaming[CAPTURE_PORT] = true;
2364
2365 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
2366 control.value = 1;
2367 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2368 if (ret) {
2369 DEBUG_PRINT_ERROR("failed to request seq header");
2370 return 1;
2371 }
2372
2373 stopped = 0;
2374 return 0;
2375 }
2376
hiermode_string(int val)2377 inline const char* hiermode_string(int val)
2378 {
2379 switch(val)
2380 {
2381 case HIER_NONE:
2382 return "No Hier";
2383 case HIER_P:
2384 return "Hier-P";
2385 case HIER_B:
2386 return "Hier-B";
2387 case HIER_P_HYBRID:
2388 return "Hybrid Hier-P";
2389 default:
2390 return "No hier";
2391 }
2392 }
2393
venc_config_print()2394 void venc_dev::venc_config_print()
2395 {
2396
2397 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
2398 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
2399
2400 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
2401 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
2402 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2403
2404 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
2405 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
2406 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2407
2408 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
2409 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
2410
2411 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
2412 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
2413
2414 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2415 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2416
2417 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
2418 session_qp_values.minqp, session_qp_values.maxqp);
2419
2420 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
2421 voptimecfg.voptime_resolution, multislice.mslice_mode,
2422 multislice.mslice_size);
2423
2424 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
2425 entropy.longentropysel, entropy.cabacmodel);
2426
2427 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
2428 dbkfilter.db_mode, dbkfilter.slicealpha_offset,
2429 dbkfilter.slicebeta_offset);
2430
2431 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
2432 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
2433
2434 DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
2435 ltrinfo.enabled, ltrinfo.count);
2436
2437 if (hier_layers.numlayers) {
2438 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
2439 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
2440 }
2441
2442 if (temporal_layers_config.nPLayers) {
2443 DEBUG_PRINT_INFO("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %u",
2444 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
2445 intra_period.num_pframes + intra_period.num_bframes + 1);
2446 }
2447
2448 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
2449
2450 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
2451
2452 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
2453
2454 DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
2455
2456 DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
2457 }
2458
venc_reconfig_reqbufs()2459 bool venc_dev::venc_reconfig_reqbufs()
2460 {
2461 struct v4l2_requestbuffers bufreq;
2462
2463 bufreq.memory = V4L2_MEMORY_USERPTR;
2464 bufreq.count = m_sInput_buff_property.actualcount;
2465 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2466 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2467 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
2468 return false;
2469 }
2470
2471 bufreq.memory = V4L2_MEMORY_USERPTR;
2472 bufreq.count = m_sOutput_buff_property.actualcount;
2473 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2474 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
2475 {
2476 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
2477 return false;
2478 }
2479 return true;
2480 }
2481
venc_flush(unsigned port)2482 unsigned venc_dev::venc_flush( unsigned port)
2483 {
2484 struct v4l2_encoder_cmd enc;
2485 DEBUG_PRINT_LOW("in %s", __func__);
2486
2487 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
2488 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
2489
2490 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
2491 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
2492 return -1;
2493 }
2494
2495 return 0;
2496
2497 }
2498
2499 //allocating I/P memory from pmem and register with the device
2500
2501
venc_use_buf(void * buf_addr,unsigned port,unsigned index)2502 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
2503 {
2504
2505 struct pmem *pmem_tmp;
2506 struct v4l2_buffer buf;
2507 struct v4l2_plane plane[VIDEO_MAX_PLANES];
2508 int rc = 0;
2509 unsigned int extra_idx;
2510
2511 pmem_tmp = (struct pmem *)buf_addr;
2512 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
2513
2514 if (port == PORT_INDEX_IN) {
2515 buf.index = index;
2516 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2517 buf.memory = V4L2_MEMORY_USERPTR;
2518 plane[0].length = pmem_tmp->size;
2519 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2520 plane[0].reserved[0] = pmem_tmp->fd;
2521 plane[0].reserved[1] = 0;
2522 plane[0].data_offset = pmem_tmp->offset;
2523 buf.m.planes = plane;
2524 buf.length = 1;
2525
2526 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2527
2528 if (rc)
2529 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2530 } else if (port == PORT_INDEX_OUT) {
2531 extra_idx = EXTRADATA_IDX(num_planes);
2532
2533 if ((num_planes > 1) && (extra_idx)) {
2534 rc = allocate_extradata();
2535
2536 if (rc)
2537 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc);
2538 }
2539
2540 buf.index = index;
2541 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2542 buf.memory = V4L2_MEMORY_USERPTR;
2543 plane[0].length = pmem_tmp->size;
2544 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2545 plane[0].reserved[0] = pmem_tmp->fd;
2546 plane[0].reserved[1] = 0;
2547 plane[0].data_offset = pmem_tmp->offset;
2548 buf.m.planes = plane;
2549 buf.length = num_planes;
2550
2551 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2552 plane[extra_idx].length = extradata_info.buffer_size;
2553 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2554 #ifdef USE_ION
2555 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2556 #endif
2557 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2558 plane[extra_idx].data_offset = 0;
2559 } else if (extra_idx >= VIDEO_MAX_PLANES) {
2560 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
2561 return OMX_ErrorBadParameter;
2562 }
2563
2564 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2565
2566 if (rc)
2567 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2568 } else {
2569 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
2570 return false;
2571 }
2572
2573 return true;
2574 }
2575
venc_free_buf(void * buf_addr,unsigned port)2576 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
2577 {
2578 struct pmem *pmem_tmp;
2579 struct venc_bufferpayload dev_buffer;
2580
2581 memset(&dev_buffer, 0, sizeof(dev_buffer));
2582 pmem_tmp = (struct pmem *)buf_addr;
2583
2584 if (port == PORT_INDEX_IN) {
2585 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2586 dev_buffer.fd = pmem_tmp->fd;
2587 dev_buffer.maped_size = pmem_tmp->size;
2588 dev_buffer.sz = pmem_tmp->size;
2589 dev_buffer.offset = pmem_tmp->offset;
2590 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2591 dev_buffer.pbuffer, \
2592 dev_buffer.fd, \
2593 dev_buffer.offset, \
2594 dev_buffer.maped_size);
2595
2596 } else if (port == PORT_INDEX_OUT) {
2597 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2598 dev_buffer.fd = pmem_tmp->fd;
2599 dev_buffer.sz = pmem_tmp->size;
2600 dev_buffer.maped_size = pmem_tmp->size;
2601 dev_buffer.offset = pmem_tmp->offset;
2602
2603 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2604 dev_buffer.pbuffer, \
2605 dev_buffer.fd, \
2606 dev_buffer.offset, \
2607 dev_buffer.maped_size);
2608 } else {
2609 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
2610 return false;
2611 }
2612
2613 return true;
2614 }
2615
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2616 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
2617 OMX_U32 width, OMX_U32 height)
2618 {
2619 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2620 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2621 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2622 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2623 src_chroma_offset = width * height;
2624
2625 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2626 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2627 //Do chroma first, so that we can convert it in-place
2628 src_buf += width * height;
2629 dst_buf += y_stride * y_scanlines;
2630 for (int line = height / 2 - 1; line >= 0; --line) {
2631 memmove(dst_buf + line * uv_stride,
2632 src_buf + line * width,
2633 width);
2634 }
2635
2636 dst_buf = src_buf = buffer->pBuffer;
2637 //Copy the Y next
2638 for (int line = height - 1; line > 0; --line) {
2639 memmove(dst_buf + line * y_stride,
2640 src_buf + line * width,
2641 width);
2642 }
2643 } else {
2644 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
2645 Insufficient bufferLen=%u v/s Required=%u",
2646 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
2647 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
2648 return false;
2649 }
2650
2651 return true;
2652 }
2653
venc_get_performance_level(OMX_U32 * perflevel)2654 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
2655 {
2656 if (!perflevel) {
2657 DEBUG_PRINT_ERROR("Null pointer error");
2658 return false;
2659 } else {
2660 *perflevel = performance_level.perflevel;
2661 return true;
2662 }
2663 }
2664
venc_get_vui_timing_info(OMX_U32 * enabled)2665 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
2666 {
2667 if (!enabled) {
2668 DEBUG_PRINT_ERROR("Null pointer error");
2669 return false;
2670 } else {
2671 *enabled = vui_timing_info.enabled;
2672 return true;
2673 }
2674 }
2675
venc_get_peak_bitrate(OMX_U32 * peakbitrate)2676 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
2677 {
2678 if (!peakbitrate) {
2679 DEBUG_PRINT_ERROR("Null pointer error");
2680 return false;
2681 } else {
2682 *peakbitrate = peak_bitrate.peakbitrate;
2683 return true;
2684 }
2685 }
2686
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2687 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
2688 {
2689 struct pmem *temp_buffer;
2690 struct v4l2_buffer buf;
2691 struct v4l2_plane plane;
2692 int rc=0;
2693 struct OMX_BUFFERHEADERTYPE *bufhdr;
2694 struct v4l2_control control;
2695 encoder_media_buffer_type * meta_buf = NULL;
2696 temp_buffer = (struct pmem *)buffer;
2697
2698 memset (&buf, 0, sizeof(buf));
2699 memset (&plane, 0, sizeof(plane));
2700
2701 if (buffer == NULL) {
2702 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
2703 return false;
2704 }
2705
2706 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2707
2708 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
2709
2710 if (pmem_data_buf) {
2711 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
2712 plane.m.userptr = (unsigned long)pmem_data_buf;
2713 plane.data_offset = bufhdr->nOffset;
2714 plane.length = bufhdr->nAllocLen;
2715 plane.bytesused = bufhdr->nFilledLen;
2716 } else {
2717 // --------------------------------------------------------------------------------------
2718 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info]
2719 // ---------------------------------------------------------------------------------------
2720 // Camera-2 1 CameraSource 0 meta-handle
2721 // Camera-3 1 GrallocSource 0 gralloc-private-handle
2722 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted)
2723 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr
2724 // ---------------------------------------------------------------------------------------
2725 if (metadatamode) {
2726 plane.m.userptr = index;
2727 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
2728
2729 if (!meta_buf) {
2730 //empty EOS buffer
2731 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
2732 plane.data_offset = bufhdr->nOffset;
2733 plane.length = bufhdr->nAllocLen;
2734 plane.bytesused = bufhdr->nFilledLen;
2735 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
2736 } else {
2737 return false;
2738 }
2739 } else if (!color_format) {
2740 int color_space = 0;
2741
2742 if ((meta_buf->buffer_type == kMetadataBufferTypeCameraSource) ||
2743 (meta_buf->buffer_type == kMetadataBufferTypeNativeHandleSource)) {
2744 if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 3 &&
2745 meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709) {
2746 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2747 color_space = V4L2_COLORSPACE_REC709;
2748 }
2749
2750 if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 2) {
2751 plane.data_offset = meta_buf->meta_handle->data[1];
2752 plane.length = meta_buf->meta_handle->data[2];
2753 plane.bytesused = meta_buf->meta_handle->data[2];
2754 }
2755 if (!camera_mode_enabled) {
2756 camera_mode_enabled = true;
2757 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
2758 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
2759 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2760 if (rc)
2761 DEBUG_PRINT_HIGH("Failed to set control for perf level");
2762 DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, meta_buf type = %d",
2763 control.id, control.value, meta_buf->buffer_type);
2764 }
2765 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
2766 fd, plane.bytesused, plane.length, buf.flags);
2767 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
2768 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
2769 fd = handle->fd;
2770 plane.data_offset = 0;
2771 plane.length = handle->size;
2772 plane.bytesused = handle->size;
2773 if ((!camera_mode_enabled) && (handle->flags & private_handle_t:: PRIV_FLAGS_CAMERA_WRITE)) {
2774 camera_mode_enabled = true;
2775 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
2776 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
2777 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2778 if (rc)
2779 DEBUG_PRINT_HIGH("Failed to set perl level");
2780 DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, flags = 0x%x",
2781 control.id, control.value, handle->flags);
2782 }
2783
2784 if (handle->base_metadata) {
2785 MetaData_t *pMeta =
2786 reinterpret_cast<MetaData_t*>(handle->base_metadata);
2787 ColorSpace_t csc = pMeta->operation & UPDATE_COLOR_SPACE ?
2788 pMeta->colorSpace : (ColorSpace_t)-1;
2789 if (csc == ITU_R_709) {
2790 buf.flags |= V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2791 DEBUG_PRINT_LOW("venc_empty_buf: force 601 -> 709 clamping");
2792 color_space = V4L2_COLORSPACE_REC709;
2793 } else if (csc == ITU_R_601_FR) {
2794 DEBUG_PRINT_LOW("venc_empty_buf: 601 full-range");
2795 color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
2796 } else if (csc == ITU_R_601) {
2797 DEBUG_PRINT_LOW("venc_empty_buf: 601 clamped");
2798 color_space = V4L2_COLORSPACE_BT878;
2799 }
2800 } else {
2801 DEBUG_PRINT_LOW("venc_empty_buf: gralloc metadata is NULL");
2802 }
2803 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
2804 ": filled %d of %d", fd, plane.bytesused, plane.length);
2805 }
2806
2807
2808 if (!streaming[OUTPUT_PORT]) {
2809 struct v4l2_format fmt;
2810 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2811 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
2812 fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space);
2813 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
2814 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
2815 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
2816 DEBUG_PRINT_ERROR("Failed setting color format in in etb %x", m_sVenc_cfg.inputformat);
2817 return false;
2818 }
2819 }
2820 } else {
2821 plane.data_offset = bufhdr->nOffset;
2822 plane.length = bufhdr->nAllocLen;
2823 plane.bytesused = bufhdr->nFilledLen;
2824 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
2825 ": filled %d of %d", fd, plane.bytesused, plane.length);
2826 }
2827 } else {
2828 plane.data_offset = bufhdr->nOffset;
2829 plane.length = bufhdr->nAllocLen;
2830 plane.bytesused = bufhdr->nFilledLen;
2831 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
2832 fd, plane.bytesused, plane.length);
2833 }
2834 }
2835
2836 buf.index = index;
2837 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2838 buf.memory = V4L2_MEMORY_USERPTR;
2839 plane.reserved[0] = fd;
2840 plane.reserved[1] = 0;
2841 buf.m.planes = &plane;
2842 buf.length = 1;
2843
2844 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2845 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
2846
2847 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
2848 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
2849 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2850
2851 if (rc) {
2852 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
2853 return false;
2854 }
2855
2856 etb++;
2857
2858 if (!streaming[OUTPUT_PORT]) {
2859 enum v4l2_buf_type buf_type;
2860 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2861 int ret;
2862 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
2863
2864 if (ret) {
2865 DEBUG_PRINT_ERROR("Failed to call streamon");
2866 if (errno == EBUSY) {
2867 hw_overload = true;
2868 }
2869 return false;
2870 } else {
2871 streaming[OUTPUT_PORT] = true;
2872 }
2873 }
2874 if (m_debug.in_buffer_log) {
2875 venc_input_log_buffers(bufhdr, fd, plane.data_offset);
2876 }
2877
2878 return true;
2879 }
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2880 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
2881 {
2882 struct pmem *temp_buffer = NULL;
2883 struct venc_buffer frameinfo;
2884 struct v4l2_buffer buf;
2885 struct v4l2_plane plane[VIDEO_MAX_PLANES];
2886 int rc = 0;
2887 unsigned int extra_idx;
2888 struct OMX_BUFFERHEADERTYPE *bufhdr;
2889
2890 if (buffer == NULL)
2891 return false;
2892
2893 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2894
2895 if (pmem_data_buf) {
2896 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
2897 plane[0].m.userptr = (unsigned long)pmem_data_buf;
2898 } else {
2899 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
2900 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
2901 }
2902
2903 buf.index = index;
2904 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2905 buf.memory = V4L2_MEMORY_USERPTR;
2906 plane[0].length = bufhdr->nAllocLen;
2907 plane[0].bytesused = bufhdr->nFilledLen;
2908 plane[0].reserved[0] = fd;
2909 plane[0].reserved[1] = 0;
2910 plane[0].data_offset = bufhdr->nOffset;
2911 buf.m.planes = plane;
2912 buf.length = num_planes;
2913
2914 extra_idx = EXTRADATA_IDX(num_planes);
2915
2916 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2917 plane[extra_idx].bytesused = 0;
2918 plane[extra_idx].length = extradata_info.buffer_size;
2919 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2920 #ifdef USE_ION
2921 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2922 #endif
2923 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2924 plane[extra_idx].data_offset = 0;
2925 } else if (extra_idx >= VIDEO_MAX_PLANES) {
2926 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
2927 return false;
2928 }
2929
2930 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2931
2932 if (rc) {
2933 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
2934 return false;
2935 }
2936
2937 ftb++;
2938 return true;
2939 }
2940
venc_set_inband_video_header(OMX_BOOL enable)2941 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
2942 {
2943 struct v4l2_control control;
2944
2945 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
2946 if(enable) {
2947 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
2948 } else {
2949 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
2950 }
2951
2952 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
2953 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2954 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
2955 return false;
2956 }
2957 return true;
2958 }
2959
venc_set_au_delimiter(OMX_BOOL enable)2960 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
2961 {
2962 struct v4l2_control control;
2963
2964 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
2965 if(enable) {
2966 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
2967 } else {
2968 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
2969 }
2970
2971 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
2972 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2973 DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
2974 return false;
2975 }
2976 return true;
2977 }
2978
venc_validate_hybridhp_params(OMX_U32 layers,OMX_U32 bFrames,OMX_U32 count,int mode)2979 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
2980 {
2981 // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
2982 if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
2983 return false;
2984
2985 // Check for bframes with Hier-P-Hybrid
2986 if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
2987 return false;
2988
2989 // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
2990 if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
2991 hier_layers.hier_mode == HIER_B || ltrinfo.count))
2992 return false;
2993
2994 // Check for LTR with Hier-P-Hybrid
2995 if (count && hier_layers.hier_mode == HIER_P_HYBRID)
2996 return false;
2997
2998 return true;
2999 }
3000
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)3001 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
3002 OMX_U32 num_layers)
3003 {
3004 struct v4l2_control control;
3005
3006 if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
3007 DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
3008 return false;
3009 }
3010
3011 if (type == QOMX_HIERARCHICALCODING_P) {
3012 // Reduce layer count by 1 before sending to driver. This avoids
3013 // driver doing the same in multiple places.
3014 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
3015 control.value = num_layers - 1;
3016 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
3017 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3018 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
3019 return false;
3020 }
3021 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3022 DEBUG_PRINT_LOW("Set H264_SVC_NAL");
3023 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
3024 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
3025 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3026 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
3027 return false;
3028 }
3029 }
3030 hier_layers.hier_mode = HIER_P;
3031 } else if (type == QOMX_HIERARCHICALCODING_B) {
3032 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
3033 DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
3034 return false;
3035 }
3036 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
3037 control.value = num_layers - 1;
3038 DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
3039 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3040 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
3041 return false;
3042 }
3043 hier_layers.hier_mode = HIER_B;
3044 } else {
3045 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
3046 return false;
3047 }
3048 hier_layers.numlayers = num_layers;
3049 return true;
3050 }
3051
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)3052 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
3053 {
3054 struct v4l2_control control;
3055
3056 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
3057
3058 if (enable == OMX_FALSE) {
3059 /* No easy way to turn off extradata to the driver
3060 * at the moment */
3061 return false;
3062 }
3063
3064 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
3065 switch (extra_data) {
3066 case OMX_ExtraDataVideoEncoderSliceInfo:
3067 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
3068 break;
3069 case OMX_ExtraDataVideoEncoderMBInfo:
3070 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
3071 break;
3072 default:
3073 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
3074 return false;
3075 }
3076
3077 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3078 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
3079 (unsigned int)extra_data, errno);
3080 return false;
3081 }
3082
3083 return true;
3084 }
3085
venc_set_slice_delivery_mode(OMX_U32 enable)3086 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
3087 {
3088 struct v4l2_control control;
3089
3090 if (enable) {
3091 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
3092 control.value = 1;
3093 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
3094
3095 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3096 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3097 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
3098 return false;
3099 } else {
3100 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
3101 slice_mode.enable = 1;
3102 }
3103 } else {
3104 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
3105 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
3106 m_sVenc_cfg.codectype);
3107 }
3108 } else {
3109 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
3110 }
3111
3112 return true;
3113 }
3114
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)3115 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
3116 {
3117 int rc;
3118 struct v4l2_control control;
3119 struct v4l2_ext_control ctrl[4];
3120 struct v4l2_ext_controls controls;
3121
3122 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
3123 ctrl[0].value = initqp->nQpI;
3124 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
3125 ctrl[1].value = initqp->nQpP;
3126 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
3127 ctrl[2].value = initqp->nQpB;
3128 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
3129 ctrl[3].value = initqp->bEnableInitQp;
3130
3131 controls.count = 4;
3132 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3133 controls.controls = ctrl;
3134
3135 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
3136 controls.controls[0].id, controls.controls[0].value,
3137 controls.controls[1].id, controls.controls[1].value,
3138 controls.controls[2].id, controls.controls[2].value,
3139 controls.controls[3].id, controls.controls[3].value);
3140
3141 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3142 if (rc) {
3143 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
3144 return false;
3145 }
3146
3147 init_qp.iframeqp = initqp->nQpI;
3148 init_qp.pframeqp = initqp->nQpP;
3149 init_qp.bframeqp = initqp->nQpB;
3150 init_qp.enableinitqp = initqp->bEnableInitQp;
3151
3152 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
3153 controls.controls[0].id, controls.controls[0].value,
3154 controls.controls[1].id, controls.controls[1].value,
3155 controls.controls[2].id, controls.controls[2].value,
3156 controls.controls[3].id, controls.controls[3].value);
3157 return true;
3158 }
3159
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)3160 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
3161 {
3162 int rc;
3163 struct v4l2_control control;
3164
3165 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
3166 control.value = i_frame_qp;
3167
3168 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3169 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3170
3171 if (rc) {
3172 DEBUG_PRINT_ERROR("Failed to set control");
3173 return false;
3174 }
3175
3176 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3177 session_qp.iframeqp = control.value;
3178
3179 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
3180 control.value = p_frame_qp;
3181
3182 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3183 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3184
3185 if (rc) {
3186 DEBUG_PRINT_ERROR("Failed to set control");
3187 return false;
3188 }
3189
3190 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3191
3192 session_qp.pframeqp = control.value;
3193
3194 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
3195 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3196
3197 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
3198 control.value = b_frame_qp;
3199
3200 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3201 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3202
3203 if (rc) {
3204 DEBUG_PRINT_ERROR("Failed to set control");
3205 return false;
3206 }
3207
3208 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3209
3210 session_qp.bframeqp = control.value;
3211 }
3212
3213 return true;
3214 }
3215
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)3216 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
3217 {
3218 int rc;
3219 struct v4l2_control control;
3220
3221 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
3222
3223 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
3224 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
3225 else
3226 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
3227 control.value = min_qp;
3228
3229 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
3230 control.id, control.value);
3231 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3232 if (rc) {
3233 DEBUG_PRINT_ERROR("Failed to set control");
3234 return false;
3235 }
3236
3237 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
3238 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
3239 else
3240 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
3241 control.value = max_qp;
3242
3243 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
3244 control.id, control.value);
3245 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3246 if (rc) {
3247 DEBUG_PRINT_ERROR("Failed to set control");
3248 return false;
3249 }
3250 } else {
3251 DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
3252 (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
3253 }
3254
3255 return true;
3256 }
3257
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)3258 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
3259 {
3260 struct venc_profile requested_profile = {0};
3261 struct ven_profilelevel requested_level = {0};
3262 unsigned long mb_per_frame = 0;
3263 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
3264 (unsigned int)eProfile, (unsigned int)eLevel);
3265 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
3266 ((m_sVenc_cfg.dvs_width + 15) >> 4);
3267
3268 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
3269 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
3270 return true;
3271 }
3272
3273 DEBUG_PRINT_LOW("Validating Profile/Level from table");
3274
3275 if (!venc_validate_profile_level(&eProfile, &eLevel)) {
3276 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
3277 return false;
3278 }
3279
3280 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3281 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
3282 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
3283 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
3284
3285 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
3286 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
3287 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
3288 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
3289 } else {
3290 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
3291 (unsigned int)eProfile);
3292 return false;
3293 }
3294
3295 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
3296 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
3297 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
3298 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
3299
3300 if (mb_per_frame >= 3600) {
3301 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
3302 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3303
3304 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
3305 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3306 } else {
3307 switch (eLevel) {
3308 case OMX_VIDEO_MPEG4Level0:
3309 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
3310 break;
3311 case OMX_VIDEO_MPEG4Level0b:
3312 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
3313 break;
3314 case OMX_VIDEO_MPEG4Level1:
3315 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
3316 break;
3317 case OMX_VIDEO_MPEG4Level2:
3318 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
3319 break;
3320 case OMX_VIDEO_MPEG4Level3:
3321 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
3322 break;
3323 case OMX_VIDEO_MPEG4Level4a:
3324 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
3325 break;
3326 case OMX_VIDEO_MPEG4Level5:
3327 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
3328 break;
3329 default:
3330 return false;
3331 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
3332 break;
3333 }
3334 }
3335 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3336
3337 switch (eProfile) {
3338 case OMX_VIDEO_H263ProfileBaseline:
3339 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
3340 break;
3341 case OMX_VIDEO_H263ProfileH320Coding:
3342 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
3343 break;
3344 case OMX_VIDEO_H263ProfileBackwardCompatible:
3345 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
3346 break;
3347 case OMX_VIDEO_H263ProfileISWV2:
3348 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
3349 break;
3350 case OMX_VIDEO_H263ProfileISWV3:
3351 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
3352 break;
3353 case OMX_VIDEO_H263ProfileHighCompression:
3354 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
3355 break;
3356 case OMX_VIDEO_H263ProfileInternet:
3357 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
3358 break;
3359 case OMX_VIDEO_H263ProfileInterlace:
3360 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
3361 break;
3362 case OMX_VIDEO_H263ProfileHighLatency:
3363 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
3364 break;
3365 default:
3366 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
3367 requested_profile.profile);
3368 return false;
3369 }
3370
3371 //profile level
3372 switch (eLevel) {
3373 case OMX_VIDEO_H263Level10:
3374 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
3375 break;
3376 case OMX_VIDEO_H263Level20:
3377 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
3378 break;
3379 case OMX_VIDEO_H263Level30:
3380 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
3381 break;
3382 case OMX_VIDEO_H263Level40:
3383 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
3384 break;
3385 case OMX_VIDEO_H263Level45:
3386 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
3387 break;
3388 case OMX_VIDEO_H263Level50:
3389 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
3390 break;
3391 case OMX_VIDEO_H263Level60:
3392 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
3393 break;
3394 case OMX_VIDEO_H263Level70:
3395 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
3396 break;
3397 default:
3398 return false;
3399 break;
3400 }
3401 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3402 if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
3403 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
3404 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
3405 eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
3406 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
3407 } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
3408 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
3409 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
3410 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
3411 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
3412 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
3413 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
3414 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
3415 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
3416 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
3417 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
3418 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
3419 } else {
3420 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
3421 requested_profile.profile);
3422 return false;
3423 }
3424
3425 //profile level
3426 switch (eLevel) {
3427 case OMX_VIDEO_AVCLevel1:
3428 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
3429 break;
3430 case OMX_VIDEO_AVCLevel1b:
3431 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
3432 break;
3433 case OMX_VIDEO_AVCLevel11:
3434 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
3435 break;
3436 case OMX_VIDEO_AVCLevel12:
3437 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
3438 break;
3439 case OMX_VIDEO_AVCLevel13:
3440 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
3441 break;
3442 case OMX_VIDEO_AVCLevel2:
3443 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
3444 break;
3445 case OMX_VIDEO_AVCLevel21:
3446 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
3447 break;
3448 case OMX_VIDEO_AVCLevel22:
3449 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
3450 break;
3451 case OMX_VIDEO_AVCLevel3:
3452 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
3453 break;
3454 case OMX_VIDEO_AVCLevel31:
3455 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
3456 break;
3457 case OMX_VIDEO_AVCLevel32:
3458 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
3459 break;
3460 case OMX_VIDEO_AVCLevel4:
3461 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
3462 break;
3463 case OMX_VIDEO_AVCLevel41:
3464 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
3465 break;
3466 case OMX_VIDEO_AVCLevel42:
3467 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
3468 break;
3469 case OMX_VIDEO_AVCLevel5:
3470 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
3471 break;
3472 case OMX_VIDEO_AVCLevel51:
3473 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
3474 break;
3475 case OMX_VIDEO_AVCLevel52:
3476 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3477 break;
3478 case OMX_VIDEO_AVCLevelMax:
3479 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3480 break;
3481 default :
3482 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
3483 requested_level.level);
3484 return false;
3485 break;
3486 }
3487 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3488 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
3489 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
3490 (unsigned int)eProfile);
3491 return false;
3492 }
3493 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
3494 m_profile_set = true;
3495 switch(eLevel) {
3496 case OMX_VIDEO_VP8Level_Version0:
3497 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
3498 break;
3499 case OMX_VIDEO_VP8Level_Version1:
3500 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
3501 break;
3502 default:
3503 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
3504 (unsigned int)eLevel);
3505 return false;
3506 break;
3507 }
3508 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3509 if (eProfile == OMX_VIDEO_HEVCProfileMain) {
3510 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
3511 } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
3512 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
3513 } else {
3514 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
3515 requested_profile.profile);
3516 return false;
3517 }
3518
3519 //profile level
3520 switch (eLevel) {
3521 case OMX_VIDEO_HEVCMainTierLevel1:
3522 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
3523 break;
3524 case OMX_VIDEO_HEVCHighTierLevel1:
3525 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
3526 break;
3527 case OMX_VIDEO_HEVCMainTierLevel2:
3528 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
3529 break;
3530 case OMX_VIDEO_HEVCHighTierLevel2:
3531 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
3532 break;
3533 case OMX_VIDEO_HEVCMainTierLevel21:
3534 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
3535 break;
3536 case OMX_VIDEO_HEVCHighTierLevel21:
3537 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
3538 break;
3539 case OMX_VIDEO_HEVCMainTierLevel3:
3540 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
3541 break;
3542 case OMX_VIDEO_HEVCHighTierLevel3:
3543 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
3544 break;
3545 case OMX_VIDEO_HEVCMainTierLevel31:
3546 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
3547 break;
3548 case OMX_VIDEO_HEVCHighTierLevel31:
3549 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
3550 break;
3551 case OMX_VIDEO_HEVCMainTierLevel4:
3552 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
3553 break;
3554 case OMX_VIDEO_HEVCHighTierLevel4:
3555 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
3556 break;
3557 case OMX_VIDEO_HEVCMainTierLevel41:
3558 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
3559 break;
3560 case OMX_VIDEO_HEVCHighTierLevel41:
3561 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
3562 break;
3563 case OMX_VIDEO_HEVCMainTierLevel5:
3564 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
3565 break;
3566 case OMX_VIDEO_HEVCHighTierLevel5:
3567 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
3568 break;
3569 case OMX_VIDEO_HEVCMainTierLevel51:
3570 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
3571 break;
3572 case OMX_VIDEO_HEVCHighTierLevel51:
3573 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
3574 break;
3575 case OMX_VIDEO_HEVCMainTierLevel52:
3576 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
3577 break;
3578 case OMX_VIDEO_HEVCHighTierLevel52:
3579 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
3580 break;
3581 case OMX_VIDEO_HEVCMainTierLevel6:
3582 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
3583 break;
3584 case OMX_VIDEO_HEVCHighTierLevel6:
3585 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
3586 break;
3587 case OMX_VIDEO_HEVCMainTierLevel61:
3588 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
3589 break;
3590 case OMX_VIDEO_HEVCHighTierLevel61:
3591 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
3592 break;
3593 default :
3594 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
3595 requested_level.level);
3596 return false;
3597 }
3598 }
3599
3600 if (!m_profile_set) {
3601 int rc;
3602 struct v4l2_control control;
3603
3604 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3605 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3606 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3607 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
3608 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3609 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
3610 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3611 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
3612 } else {
3613 DEBUG_PRINT_ERROR("Wrong CODEC");
3614 return false;
3615 }
3616
3617 control.value = requested_profile.profile;
3618
3619 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3620 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3621
3622 if (rc) {
3623 DEBUG_PRINT_ERROR("Failed to set control");
3624 return false;
3625 }
3626
3627 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3628
3629 codec_profile.profile = control.value;
3630 m_profile_set = true;
3631 }
3632
3633 if (!m_level_set) {
3634 int rc;
3635 struct v4l2_control control;
3636
3637 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3638 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3639 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3640 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
3641 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3642 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
3643 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3644 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3645 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
3646 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
3647 } else {
3648 DEBUG_PRINT_ERROR("Wrong CODEC");
3649 return false;
3650 }
3651
3652 control.value = requested_level.level;
3653
3654 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3655 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3656
3657 if (rc) {
3658 DEBUG_PRINT_ERROR("Failed to set control");
3659 return false;
3660 }
3661
3662 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3663
3664 profile_level.level = control.value;
3665 m_level_set = true;
3666 }
3667
3668 return true;
3669 }
3670
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)3671 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
3672 {
3673
3674 struct venc_voptimingcfg vop_timing_cfg;
3675
3676 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
3677 (unsigned int)TimeIncRes);
3678
3679 vop_timing_cfg.voptime_resolution = TimeIncRes;
3680
3681 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
3682 return true;
3683 }
3684
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)3685 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
3686 {
3687
3688 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
3689 int rc;
3690 struct v4l2_control control;
3691 int pframe = 0, bframe = 0;
3692
3693 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
3694 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
3695 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
3696 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
3697 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3698 nBFrames=0;
3699 }
3700
3701 if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0)) {
3702 DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
3703 return false;
3704 }
3705
3706 intra_period.num_pframes = nPFrames;
3707 intra_period.num_bframes = nBFrames;
3708
3709 if (!venc_calibrate_gop())
3710 {
3711 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
3712 return false;
3713 }
3714
3715 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
3716 control.value = intra_period.num_pframes;
3717 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3718
3719 if (rc) {
3720 DEBUG_PRINT_ERROR("Failed to set control");
3721 return false;
3722 }
3723
3724 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3725
3726 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
3727 control.value = intra_period.num_bframes;
3728 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3729 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3730
3731 if (rc) {
3732 DEBUG_PRINT_ERROR("Failed to set control");
3733 return false;
3734 }
3735
3736 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
3737
3738 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3739 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3740 control.value = 1;
3741
3742 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3743
3744 if (rc) {
3745 DEBUG_PRINT_ERROR("Failed to set control");
3746 return false;
3747 }
3748
3749 idrperiod.idrperiod = 1;
3750 }
3751
3752 return true;
3753 }
3754
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)3755 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
3756 {
3757 int rc = 0;
3758 struct v4l2_control control;
3759 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
3760 (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
3761
3762 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
3763 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
3764 return false;
3765 }
3766
3767 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
3768 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
3769 return false;
3770 }
3771
3772 if (!intra_period.num_bframes)
3773 intra_period.num_pframes = nPFrames;
3774 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3775 control.value = nIDRPeriod;
3776
3777 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3778
3779 if (rc) {
3780 DEBUG_PRINT_ERROR("Failed to set control");
3781 return false;
3782 }
3783
3784 idrperiod.idrperiod = nIDRPeriod;
3785 return true;
3786 }
3787
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)3788 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
3789 {
3790 int rc = 0;
3791 struct v4l2_control control;
3792
3793 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
3794
3795 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
3796 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
3797
3798 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
3799 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3800
3801 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3802 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3803
3804 if (rc) {
3805 DEBUG_PRINT_ERROR("Failed to set control");
3806 return false;
3807 }
3808
3809 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3810 entropy.longentropysel = control.value;
3811
3812 if (i_cabac_level == 0) {
3813 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
3814 } else if (i_cabac_level == 1) {
3815 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
3816 } else if (i_cabac_level == 2) {
3817 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
3818 }
3819
3820 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
3821 //control.value = entropy_cfg.cabacmodel;
3822 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3823 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3824
3825 if (rc) {
3826 DEBUG_PRINT_ERROR("Failed to set control");
3827 return false;
3828 }
3829
3830 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3831 entropy.cabacmodel=control.value;
3832 } else if (!enable) {
3833 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
3834 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3835 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3836 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3837
3838 if (rc) {
3839 DEBUG_PRINT_ERROR("Failed to set control");
3840 return false;
3841 }
3842
3843 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3844 entropy.longentropysel=control.value;
3845 } else {
3846 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
3847 return false;
3848 }
3849
3850 return true;
3851 }
3852
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)3853 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
3854 {
3855 int rc;
3856 struct v4l2_control control;
3857 bool status = true;
3858
3859 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) {
3860 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
3861 } else {
3862 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3863 }
3864
3865 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3866 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3867 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3868
3869 if (rc) {
3870 DEBUG_PRINT_ERROR("Failed to set control");
3871 return false;
3872 }
3873
3874 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3875 multislice.mslice_mode=control.value;
3876
3877 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
3878
3879 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
3880 control.value = nSlicesize;
3881 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
3882 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3883
3884 if (rc) {
3885 DEBUG_PRINT_ERROR("Failed to set control");
3886 return false;
3887 }
3888
3889 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3890 multislice.mslice_size=control.value;
3891
3892 }
3893
3894 return status;
3895 }
3896
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)3897 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
3898 {
3899 bool status = true;
3900 int rc;
3901 struct v4l2_control control_mode,control_mbs;
3902 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
3903
3904 // There is no disabled mode. Disabled mode is indicated by a 0 count.
3905 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
3906 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
3907 return status;
3908 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
3909 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3910 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
3911 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
3912 control_mbs.value=irMBs;
3913 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
3914 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3915 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
3916 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3917 control_mbs.value=irMBs;
3918 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
3919 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3920 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
3921 } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
3922 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3923 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
3924 control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3925 control_mbs.value = irMBs;
3926 } else {
3927 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
3928 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
3929 return false;
3930 }
3931
3932 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
3933 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
3934
3935 if (rc) {
3936 DEBUG_PRINT_ERROR("Failed to set control");
3937 return false;
3938 }
3939
3940 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
3941
3942 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
3943 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
3944
3945 if (rc) {
3946 DEBUG_PRINT_ERROR("Failed to set control");
3947 return false;
3948 }
3949
3950 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
3951
3952 intra_refresh.irmode = control_mode.value;
3953 intra_refresh.mbcount = control_mbs.value;
3954
3955 return status;
3956 }
3957
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)3958 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
3959 {
3960 bool status = true;
3961 struct venc_headerextension hec_cfg;
3962 struct venc_multiclicecfg multislice_cfg;
3963 int rc;
3964 OMX_U32 resynchMarkerSpacingBytes = 0;
3965 struct v4l2_control control;
3966
3967 memset(&control, 0, sizeof(control));
3968
3969 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3970 if (error_resilience->bEnableHEC) {
3971 hec_cfg.header_extension = 1;
3972 } else {
3973 hec_cfg.header_extension = 0;
3974 }
3975
3976 hec.header_extension = error_resilience->bEnableHEC;
3977 }
3978
3979 if (error_resilience->bEnableRVLC) {
3980 DEBUG_PRINT_ERROR("RVLC is not Supported");
3981 return false;
3982 }
3983
3984 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3985 (error_resilience->bEnableDataPartitioning)) {
3986 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
3987 return false;
3988 }
3989
3990 if (error_resilience->nResynchMarkerSpacing) {
3991 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
3992 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
3993 }
3994 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3995 (error_resilience->nResynchMarkerSpacing)) {
3996 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
3997 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3998 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3999 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
4000 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
4001 error_resilience->bEnableDataPartitioning) {
4002 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
4003 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
4004 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
4005 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
4006 } else {
4007 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
4008 multislice_cfg.mslice_size = 0;
4009 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
4010 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
4011 }
4012
4013 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
4014 multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
4015 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4016 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4017
4018 if (rc) {
4019 DEBUG_PRINT_ERROR("Failed to set Slice mode control");
4020 return false;
4021 }
4022
4023 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4024 multislice.mslice_mode=control.value;
4025
4026 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
4027 control.value = resynchMarkerSpacingBytes;
4028 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4029
4030 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4031
4032 if (rc) {
4033 DEBUG_PRINT_ERROR("Failed to set MAX MB control");
4034 return false;
4035 }
4036
4037 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4038 multislice.mslice_mode = multislice_cfg.mslice_mode;
4039 multislice.mslice_size = multislice_cfg.mslice_size;
4040 return status;
4041 }
4042
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)4043 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
4044 {
4045 int rc;
4046 struct v4l2_control control;
4047 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
4048
4049 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
4050 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
4051 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
4052 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
4053 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
4054 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
4055 }
4056
4057 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4058 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4059
4060 if (rc) {
4061 return false;
4062 }
4063
4064 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4065
4066 dbkfilter.db_mode=control.value;
4067
4068 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
4069 control.value=0;
4070
4071 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4072 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4073
4074 if (rc) {
4075 return false;
4076 }
4077
4078 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4079 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
4080 control.value=0;
4081 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4082 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4083
4084 if (rc) {
4085 return false;
4086 }
4087
4088 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4089
4090
4091 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
4092 return true;
4093 }
4094
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)4095 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
4096 {
4097 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
4098 (unsigned int)nTargetBitrate);
4099 struct v4l2_control control;
4100 int rc = 0;
4101 control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
4102 control.value = nTargetBitrate;
4103
4104 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4105 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4106
4107 if (rc) {
4108 DEBUG_PRINT_ERROR("Failed to set control");
4109 return false;
4110 }
4111
4112 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4113
4114
4115 m_sVenc_cfg.targetbitrate = control.value;
4116 bitrate.target_bitrate = control.value;
4117
4118 if (!config) {
4119 m_level_set = false;
4120
4121 if (venc_set_profile_level(0, 0)) {
4122 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
4123 }
4124 }
4125
4126 return true;
4127 }
4128
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)4129 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
4130 {
4131 struct v4l2_streamparm parm;
4132 int rc = 0;
4133 struct venc_framerate frame_rate_cfg;
4134 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
4135 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4136 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
4137 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
4138
4139 if (frame_rate_cfg.fps_numerator > 0)
4140 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
4141
4142 if (rc) {
4143 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
4144 return false;
4145 }
4146
4147 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
4148 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
4149
4150 if (!config) {
4151 m_level_set = false;
4152
4153 if (venc_set_profile_level(0, 0)) {
4154 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
4155 }
4156 }
4157
4158 return true;
4159 }
4160
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)4161 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
4162 {
4163 struct v4l2_format fmt;
4164 int color_space = 0;
4165 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
4166
4167 if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar ||
4168 (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
4169 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
4170 color_space = V4L2_COLORSPACE_BT878;
4171 } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) {
4172 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
4173 color_space = V4L2_COLORSPACE_BT878;
4174 } else {
4175 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
4176 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
4177 DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
4178 }
4179
4180 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4181 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
4182 fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space);
4183 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
4184 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
4185
4186 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
4187 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
4188 return false;
4189 }
4190
4191 return true;
4192 }
4193
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)4194 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
4195 {
4196 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
4197
4198 if (intra_vop_refresh == OMX_TRUE) {
4199 struct v4l2_control control;
4200 int rc;
4201 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
4202 control.value = 1;
4203 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4204 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4205
4206 if (rc) {
4207 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
4208 return false;
4209 }
4210
4211 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4212 } else {
4213 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
4214 }
4215
4216 return true;
4217 }
4218
venc_set_deinterlace(OMX_U32 enable)4219 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
4220 {
4221 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
4222 struct v4l2_control control;
4223 int rc;
4224 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
4225 if (enable)
4226 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
4227 else
4228 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
4229
4230 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4231 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4232 if (rc) {
4233 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
4234 return false;
4235 }
4236 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4237 deinterlace_enabled = true;
4238 return true;
4239 }
4240
venc_calibrate_gop()4241 bool venc_dev::venc_calibrate_gop()
4242 {
4243 int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
4244 int num_sub_gops_in_a_gop;
4245 nPframes = intra_period.num_pframes;
4246 nBframes = intra_period.num_bframes;
4247 nLayers = hier_layers.numlayers;
4248
4249 if (!nPframes) {
4250 DEBUG_PRINT_ERROR("nPframes should be non-zero\n");
4251 return false;
4252 }
4253
4254 if (nLayers > 1) { /*Multi-layer encoding*/
4255 sub_gop_size = 1 << (nLayers - 1);
4256 /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
4257 * below calculations we are ignoring +1 . Ignoring +1 in below
4258 * calculations is not a mistake but intentional.
4259 */
4260 gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
4261 num_sub_gops_in_a_gop = gop_size/sub_gop_size;
4262 if (nBframes) { /*Hier-B case*/
4263 /*
4264 * Frame Type--> I B B B P B B B P I B B P ...
4265 * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ...
4266 * nPframes = 2, nBframes = 6, nLayers = 3
4267 *
4268 * Intention is to keep the intraperiod as close as possible to what is desired
4269 * by the client while adjusting nPframes and nBframes to meet other constraints.
4270 * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2
4271 * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
4272 *
4273 * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
4274 * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
4275 */
4276 nPframes = num_sub_gops_in_a_gop;
4277 nBframes = gop_size - nPframes;
4278 } else { /*Hier-P case*/
4279 /*
4280 * Frame Type--> I P P P P P P P I P P P P ...
4281 * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ...
4282 * nPframes = 7, nBframes = 0, nLayers = 3
4283 *
4284 * Intention is to keep the intraperiod as close as possible to what is desired
4285 * by the client while adjusting nPframes and nBframes to meet other constraints.
4286 * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
4287 * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
4288 *
4289 * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
4290 * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
4291 */
4292 nPframes = gop_size - 1;
4293 }
4294 } else { /*Single-layer encoding*/
4295 if (nBframes) {
4296 /* I P B B B P B B B P B B B I P B B...
4297 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...
4298 * nPframes = 3, nBframes = 9, nLayers = 0
4299 *
4300 * ratio is rounded,
4301 * eg1: nPframes = 9, nBframes = 11 => ratio = 1
4302 * eg2: nPframes = 9, nBframes = 16 => ratio = 2
4303 */
4304 ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
4305 nBframes = ratio * nPframes;
4306 }
4307 }
4308 DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
4309 intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
4310 intra_period.num_pframes = nPframes;
4311 intra_period.num_bframes = nBframes;
4312 hier_layers.numlayers = nLayers;
4313 return true;
4314 }
4315
venc_set_hybrid_hierp(OMX_U32 layers)4316 bool venc_dev::venc_set_hybrid_hierp(OMX_U32 layers)
4317 {
4318 DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers: %u", layers);
4319 struct v4l2_control control;
4320 int rc;
4321
4322 if (!venc_validate_hybridhp_params(layers, 0, 0, (int) HIER_P_HYBRID)) {
4323 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4324 return false;
4325 }
4326
4327 if (!layers || layers > MAX_HYB_HIERP_LAYERS) {
4328 DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", layers);
4329 return false;
4330 }
4331
4332 hier_layers.numlayers = layers;
4333 hier_layers.hier_mode = HIER_P_HYBRID;
4334 if (venc_calibrate_gop()) {
4335 // Update the driver with the new nPframes and nBframes
4336 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
4337 control.value = intra_period.num_pframes;
4338 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4339 if (rc) {
4340 DEBUG_PRINT_ERROR("Failed to set control");
4341 return false;
4342 }
4343
4344 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
4345 control.value = intra_period.num_bframes;
4346 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4347 if (rc) {
4348 DEBUG_PRINT_ERROR("Failed to set control");
4349 return false;
4350 }
4351 DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
4352 intra_period.num_pframes, intra_period.num_bframes);
4353 } else {
4354 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
4355 return false;
4356 }
4357
4358 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
4359 control.value = layers - 1;
4360
4361 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
4362 control.id, control.value);
4363
4364 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4365 if (rc) {
4366 DEBUG_PRINT_ERROR("Failed to set hybrid hierp %d", rc);
4367 return false;
4368 }
4369
4370 DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
4371 control.id, control.value);
4372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
4373 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
4374 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4375 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
4376 return false;
4377 }
4378 return true;
4379 }
4380
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)4381 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
4382 {
4383 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
4384 struct v4l2_control control;
4385 struct v4l2_ext_control ctrl[2];
4386 struct v4l2_ext_controls controls;
4387 int rc;
4388
4389 if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
4390 DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
4391 return false;
4392 }
4393
4394 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
4395 if (enable)
4396 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
4397 else
4398 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
4399
4400 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
4401 if (enable && count > 0)
4402 ctrl[1].value = count;
4403 else if (enable)
4404 ctrl[1].value = 1;
4405 else
4406 ctrl[1].value = 0;
4407
4408 controls.count = 2;
4409 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4410 controls.controls = ctrl;
4411
4412 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
4413 controls.controls[0].id, controls.controls[0].value,
4414 controls.controls[1].id, controls.controls[1].value);
4415
4416 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4417 if (rc) {
4418 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
4419 return false;
4420 }
4421 ltrinfo.enabled = enable;
4422 ltrinfo.count = count;
4423
4424 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
4425 controls.controls[0].id, controls.controls[0].value,
4426 controls.controls[1].id, controls.controls[1].value);
4427
4428 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4429 control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR;
4430
4431 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4432 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
4433 return false;
4434 }
4435
4436 if (!venc_set_profile_level(0, 0)) {
4437 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
4438 __func__);
4439 } else {
4440 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
4441 __func__, codec_profile.profile, profile_level.level);
4442 }
4443
4444 return true;
4445 }
4446
venc_set_useltr(OMX_U32 frameIdx)4447 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
4448 {
4449 DEBUG_PRINT_LOW("venc_use_goldenframe");
4450 int rc = true;
4451 struct v4l2_control control;
4452
4453 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
4454 control.value = frameIdx;
4455
4456 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4457 if (rc) {
4458 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
4459 return false;
4460 }
4461
4462 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4463 control.id, control.value);
4464 return true;
4465 }
4466
venc_set_markltr(OMX_U32 frameIdx)4467 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
4468 {
4469 DEBUG_PRINT_LOW("venc_set_goldenframe");
4470 int rc = true;
4471 struct v4l2_control control;
4472
4473 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
4474 control.value = frameIdx;
4475
4476 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4477 if (rc) {
4478 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
4479 return false;
4480 }
4481
4482 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4483 control.id, control.value);
4484 return true;
4485 }
4486
venc_set_vpe_rotation(OMX_S32 rotation_angle)4487 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
4488 {
4489 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
4490 struct v4l2_control control;
4491 int rc;
4492 struct v4l2_format fmt;
4493 struct v4l2_requestbuffers bufreq;
4494
4495 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
4496 if (rotation_angle == 0)
4497 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
4498 else if (rotation_angle == 90)
4499 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
4500 else if (rotation_angle == 180)
4501 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
4502 else if (rotation_angle == 270)
4503 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
4504 else {
4505 DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
4506 return false;
4507 }
4508
4509 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4510 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4511 if (rc) {
4512 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
4513 return false;
4514 }
4515 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4516
4517 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4518 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
4519 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
4520 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
4521 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
4522 DEBUG_PRINT_ERROR("Failed to set format on capture port");
4523 return false;
4524 }
4525
4526 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
4527 bufreq.memory = V4L2_MEMORY_USERPTR;
4528 bufreq.count = m_sOutput_buff_property.actualcount;
4529 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4530 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
4531 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
4532 return false;
4533 }
4534 if (bufreq.count >= m_sOutput_buff_property.mincount)
4535 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
4536
4537 return true;
4538 }
4539
venc_set_searchrange()4540 bool venc_dev::venc_set_searchrange()
4541 {
4542 DEBUG_PRINT_LOW("venc_set_searchrange");
4543 struct v4l2_control control;
4544 struct v4l2_ext_control ctrl[6];
4545 struct v4l2_ext_controls controls;
4546 int rc;
4547
4548 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4549 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4550 ctrl[0].value = 16;
4551 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4552 ctrl[1].value = 4;
4553 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4554 ctrl[2].value = 16;
4555 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4556 ctrl[3].value = 4;
4557 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4558 ctrl[4].value = 12;
4559 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4560 ctrl[5].value = 4;
4561 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
4562 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
4563 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4564 ctrl[0].value = 16;
4565 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4566 ctrl[1].value = 4;
4567 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4568 ctrl[2].value = 16;
4569 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4570 ctrl[3].value = 4;
4571 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4572 ctrl[4].value = 12;
4573 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4574 ctrl[5].value = 4;
4575 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4576 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
4577 ctrl[0].value = 4;
4578 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
4579 ctrl[1].value = 4;
4580 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
4581 ctrl[2].value = 4;
4582 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
4583 ctrl[3].value = 4;
4584 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
4585 ctrl[4].value = 4;
4586 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
4587 ctrl[5].value = 4;
4588 } else {
4589 DEBUG_PRINT_ERROR("Invalid codec type");
4590 return false;
4591 }
4592 controls.count = 6;
4593 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
4594 controls.controls = ctrl;
4595
4596 DEBUG_PRINT_LOW(" Calling IOCTL set control for"
4597 "id=%x, val=%d id=%x, val=%d"
4598 "id=%x, val=%d id=%x, val=%d"
4599 "id=%x, val=%d id=%x, val=%d",
4600 controls.controls[0].id, controls.controls[0].value,
4601 controls.controls[1].id, controls.controls[1].value,
4602 controls.controls[2].id, controls.controls[2].value,
4603 controls.controls[3].id, controls.controls[3].value,
4604 controls.controls[4].id, controls.controls[4].value,
4605 controls.controls[5].id, controls.controls[5].value);
4606
4607 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
4608 if (rc) {
4609 DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
4610 return false;
4611 }
4612 return true;
4613 }
4614
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)4615 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
4616 {
4617 bool status = true;
4618 struct v4l2_control control;
4619 int rc = 0;
4620 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
4621
4622 switch (eControlRate) {
4623 case OMX_Video_ControlRateDisable:
4624 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
4625 break;
4626 case OMX_Video_ControlRateVariableSkipFrames:
4627 (supported_rc_modes & RC_VBR_VFR) ?
4628 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
4629 status = false;
4630 break;
4631 case OMX_Video_ControlRateVariable:
4632 (supported_rc_modes & RC_VBR_CFR) ?
4633 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
4634 status = false;
4635 break;
4636 case OMX_Video_ControlRateConstantSkipFrames:
4637 (supported_rc_modes & RC_CBR_VFR) ?
4638 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
4639 status = false;
4640 break;
4641 case OMX_Video_ControlRateConstant:
4642 (supported_rc_modes & RC_CBR_CFR) ?
4643 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
4644 status = false;
4645 break;
4646 default:
4647 status = false;
4648 break;
4649 }
4650
4651 if (status) {
4652
4653 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4654 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4655
4656 if (rc) {
4657 DEBUG_PRINT_ERROR("Failed to set control");
4658 return false;
4659 }
4660
4661 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4662
4663 rate_ctrl.rcmode = control.value;
4664 }
4665
4666 return status;
4667 }
4668
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)4669 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
4670 {
4671 bool status = true;
4672 struct v4l2_control control;
4673 int rc = 0;
4674 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
4675
4676 switch (ePerfLevel) {
4677 case OMX_QCOM_PerfLevelNominal:
4678 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
4679 break;
4680 case OMX_QCOM_PerfLevelTurbo:
4681 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
4682 break;
4683 default:
4684 status = false;
4685 break;
4686 }
4687
4688 if (status) {
4689 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4690 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4691
4692 if (rc) {
4693 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
4694 return false;
4695 }
4696
4697 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4698 }
4699 return status;
4700 }
4701
venc_set_perf_mode(OMX_U32 mode)4702 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
4703 {
4704 struct v4l2_control control;
4705 if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
4706 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
4707 control.value = mode;
4708 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
4709 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4710 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
4711 return false;
4712 }
4713 return true;
4714 } else {
4715 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
4716 return false;
4717 }
4718 }
4719
venc_set_vui_timing_info(OMX_BOOL enable)4720 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
4721 {
4722 struct v4l2_control control;
4723 int rc = 0;
4724 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
4725
4726 if (enable)
4727 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
4728 else
4729 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
4730
4731 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
4732 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4733 if (rc) {
4734 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
4735 return false;
4736 }
4737 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
4738 return true;
4739 }
4740
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)4741 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
4742 {
4743 struct v4l2_control control;
4744 int rc = 0;
4745 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
4746 control.value = nPeakBitrate;
4747
4748 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
4749
4750 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4751 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4752
4753 if (rc) {
4754 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
4755 return false;
4756 }
4757
4758 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4759
4760 return true;
4761 }
4762
venc_set_vpx_error_resilience(OMX_BOOL enable)4763 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
4764 {
4765 struct v4l2_control control;
4766 int rc = 0;
4767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
4768
4769 if (enable)
4770 control.value = 1;
4771 else
4772 control.value = 0;
4773
4774 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
4775
4776 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4777
4778 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
4779 if (rc) {
4780 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
4781 return false;
4782 }
4783 vpx_err_resilience.enable = 1;
4784 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4785 return true;
4786 }
4787
venc_set_session_priority(OMX_U32 priority)4788 bool venc_dev::venc_set_session_priority(OMX_U32 priority) {
4789 struct v4l2_control control;
4790
4791 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
4792 switch(priority) {
4793 case 0:
4794 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
4795 break;
4796 case 1:
4797 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4798 break;
4799 default:
4800 priority = 1;
4801 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4802 DEBUG_PRINT_ERROR("Unsupported priority level %u", priority);
4803 break;
4804 }
4805
4806 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4807 DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
4808 priority == 0 ? "ENABLE" : "DISABLE");
4809 return false;
4810 }
4811
4812 sess_priority.priority = priority;
4813
4814 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
4815 control.id, control.value);
4816 return true;
4817 }
4818
venc_set_operatingrate(OMX_U32 rate)4819 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
4820 struct v4l2_control control;
4821
4822 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
4823 control.value = rate;
4824
4825 DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
4826 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
4827
4828 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4829 hw_overload = errno == EBUSY;
4830 DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
4831 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
4832 return false;
4833 }
4834 operating_rate = rate;
4835 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16);
4836 return true;
4837 }
4838
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers)4839 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
4840 OMX_U32 *nMaxBLayers) {
4841 temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
4842 temporal_layers_config.nMaxBLayers = 0;
4843
4844 *nMaxLayers = temporal_layers_config.nMaxLayers;
4845 *nMaxBLayers = temporal_layers_config.nMaxBLayers;
4846 return true;
4847 }
4848
venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE * pTemporalParams)4849 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
4850 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
4851
4852 if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
4853 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
4854 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
4855 DEBUG_PRINT_ERROR("Temporal layers not supported for %ld", m_sVenc_cfg.codectype);
4856 return OMX_ErrorUnsupportedSetting;
4857 }
4858
4859 if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
4860 (pTemporalParams->nBLayerCountActual != 0 ||
4861 pTemporalParams->nPLayerCountActual != 1)) {
4862 return OMX_ErrorBadParameter;
4863 } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
4864 pTemporalParams->nPLayerCountActual < 1) {
4865 return OMX_ErrorBadParameter;
4866 }
4867
4868 if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
4869 DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers (%u) exceeds supported max(%u)",
4870 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
4871 return OMX_ErrorBadParameter;
4872 } else if (pTemporalParams->nPLayerCountActual >
4873 temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
4874 DEBUG_PRINT_ERROR("TemporalLayer: Requested layers (%u) exceeds supported max(%u)",
4875 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
4876 temporal_layers_config.nMaxLayers);
4877 return OMX_ErrorBadParameter;
4878 }
4879
4880 // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
4881 // use hybrid-HP for best results
4882 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
4883 pTemporalParams->nBLayerCountActual == 0 &&
4884 (rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR)) {
4885 if (!venc_set_hybrid_hierp(pTemporalParams->nPLayerCountActual)) {
4886 DEBUG_PRINT_ERROR("Failed to enable (hybrid) Hier-P with %u layers",
4887 pTemporalParams->nPLayerCountActual);
4888 return OMX_ErrorUnsupportedSetting;
4889 }
4890 temporal_layers_config.hier_mode = HIER_P_HYBRID;
4891 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
4892 temporal_layers_config.nBLayers = 0;
4893
4894 // we ignore layer-size bitrate request for this mode
4895 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
4896 pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
4897
4898 } else {
4899 if (pTemporalParams->nBLayerCountActual == 0) {
4900 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, pTemporalParams->nPLayerCountActual)) {
4901 DEBUG_PRINT_ERROR("Failed to enable Hier-P with %u layers",
4902 pTemporalParams->nPLayerCountActual);
4903 return OMX_ErrorUnsupportedSetting;
4904 }
4905 temporal_layers_config.hier_mode = HIER_P;
4906 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
4907 temporal_layers_config.nBLayers = 0;
4908
4909 // TODO: handle layer-wise bitrate request. For now, disregard the setting
4910 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
4911 pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
4912
4913 } else {
4914 // we do not support B-frames with enhancement layers for now
4915 }
4916 }
4917
4918 return OMX_ErrorNone;
4919 }
4920
venc_set_temporal_layers_internal()4921 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
4922 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
4923 memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
4924
4925 if (!temporal_layers_config.nPLayers) {
4926 return OMX_ErrorNone;
4927 }
4928 pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4929 pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
4930 pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
4931 pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4932 pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
4933 pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
4934 pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
4935 if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
4936 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
4937 pTemporalParams.nBitrateRatios[i] =
4938 temporal_layers_config.nTemporalLayerBitrateRatio[i];
4939 }
4940 }
4941 return venc_set_temporal_layers(&pTemporalParams);
4942 }
4943
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)4944 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
4945 {
4946 bool status = true;
4947
4948 if (eProfile == NULL || eLevel == NULL) {
4949 return false;
4950 }
4951
4952 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4953 switch (codec_profile.profile) {
4954 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4955 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4956 break;
4957 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4958 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4959 break;
4960 default:
4961 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
4962 status = false;
4963 break;
4964 }
4965
4966 if (!status) {
4967 return status;
4968 }
4969
4970 //profile level
4971 switch (profile_level.level) {
4972 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
4973 *eLevel = OMX_VIDEO_MPEG4Level0;
4974 break;
4975 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
4976 *eLevel = OMX_VIDEO_MPEG4Level0b;
4977 break;
4978 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
4979 *eLevel = OMX_VIDEO_MPEG4Level1;
4980 break;
4981 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
4982 *eLevel = OMX_VIDEO_MPEG4Level2;
4983 break;
4984 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
4985 *eLevel = OMX_VIDEO_MPEG4Level3;
4986 break;
4987 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
4988 *eLevel = OMX_VIDEO_MPEG4Level4;
4989 break;
4990 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
4991 *eLevel = OMX_VIDEO_MPEG4Level5;
4992 break;
4993 default:
4994 *eLevel = OMX_VIDEO_MPEG4LevelMax;
4995 status = false;
4996 break;
4997 }
4998 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4999 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
5000 *eProfile = OMX_VIDEO_H263ProfileBaseline;
5001 } else {
5002 *eProfile = OMX_VIDEO_H263ProfileMax;
5003 return false;
5004 }
5005
5006 switch (profile_level.level) {
5007 case VEN_LEVEL_H263_10:
5008 *eLevel = OMX_VIDEO_H263Level10;
5009 break;
5010 case VEN_LEVEL_H263_20:
5011 *eLevel = OMX_VIDEO_H263Level20;
5012 break;
5013 case VEN_LEVEL_H263_30:
5014 *eLevel = OMX_VIDEO_H263Level30;
5015 break;
5016 case VEN_LEVEL_H263_40:
5017 *eLevel = OMX_VIDEO_H263Level40;
5018 break;
5019 case VEN_LEVEL_H263_45:
5020 *eLevel = OMX_VIDEO_H263Level45;
5021 break;
5022 case VEN_LEVEL_H263_50:
5023 *eLevel = OMX_VIDEO_H263Level50;
5024 break;
5025 case VEN_LEVEL_H263_60:
5026 *eLevel = OMX_VIDEO_H263Level60;
5027 break;
5028 case VEN_LEVEL_H263_70:
5029 *eLevel = OMX_VIDEO_H263Level70;
5030 break;
5031 default:
5032 *eLevel = OMX_VIDEO_H263LevelMax;
5033 status = false;
5034 break;
5035 }
5036 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5037 switch (codec_profile.profile) {
5038 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
5039 *eProfile = OMX_VIDEO_AVCProfileBaseline;
5040 break;
5041 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
5042 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
5043 break;
5044 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
5045 *eProfile = OMX_VIDEO_AVCProfileMain;
5046 break;
5047 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
5048 *eProfile = OMX_VIDEO_AVCProfileHigh;
5049 break;
5050 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
5051 *eProfile = OMX_VIDEO_AVCProfileExtended;
5052 break;
5053 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
5054 *eProfile = OMX_VIDEO_AVCProfileHigh10;
5055 break;
5056 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
5057 *eProfile = OMX_VIDEO_AVCProfileHigh422;
5058 break;
5059 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
5060 *eProfile = OMX_VIDEO_AVCProfileHigh444;
5061 break;
5062 default:
5063 *eProfile = OMX_VIDEO_AVCProfileMax;
5064 status = false;
5065 break;
5066 }
5067
5068 if (!status) {
5069 return status;
5070 }
5071
5072 switch (profile_level.level) {
5073 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
5074 *eLevel = OMX_VIDEO_AVCLevel1;
5075 break;
5076 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
5077 *eLevel = OMX_VIDEO_AVCLevel1b;
5078 break;
5079 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
5080 *eLevel = OMX_VIDEO_AVCLevel11;
5081 break;
5082 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
5083 *eLevel = OMX_VIDEO_AVCLevel12;
5084 break;
5085 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
5086 *eLevel = OMX_VIDEO_AVCLevel13;
5087 break;
5088 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
5089 *eLevel = OMX_VIDEO_AVCLevel2;
5090 break;
5091 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
5092 *eLevel = OMX_VIDEO_AVCLevel21;
5093 break;
5094 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
5095 *eLevel = OMX_VIDEO_AVCLevel22;
5096 break;
5097 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
5098 *eLevel = OMX_VIDEO_AVCLevel3;
5099 break;
5100 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
5101 *eLevel = OMX_VIDEO_AVCLevel31;
5102 break;
5103 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
5104 *eLevel = OMX_VIDEO_AVCLevel32;
5105 break;
5106 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
5107 *eLevel = OMX_VIDEO_AVCLevel4;
5108 break;
5109 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
5110 *eLevel = OMX_VIDEO_AVCLevel41;
5111 break;
5112 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
5113 *eLevel = OMX_VIDEO_AVCLevel42;
5114 break;
5115 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
5116 *eLevel = OMX_VIDEO_AVCLevel5;
5117 break;
5118 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
5119 *eLevel = OMX_VIDEO_AVCLevel51;
5120 break;
5121 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
5122 *eLevel = OMX_VIDEO_AVCLevel52;
5123 break;
5124 default :
5125 *eLevel = OMX_VIDEO_AVCLevelMax;
5126 status = false;
5127 break;
5128 }
5129 }
5130 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
5131 switch (codec_profile.profile) {
5132 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
5133 *eProfile = OMX_VIDEO_VP8ProfileMain;
5134 break;
5135 default:
5136 *eProfile = OMX_VIDEO_VP8ProfileMax;
5137 status = false;
5138 break;
5139 }
5140 if (!status) {
5141 return status;
5142 }
5143
5144 switch (profile_level.level) {
5145 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
5146 *eLevel = OMX_VIDEO_VP8Level_Version0;
5147 break;
5148 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
5149 *eLevel = OMX_VIDEO_VP8Level_Version1;
5150 break;
5151 default:
5152 *eLevel = OMX_VIDEO_VP8LevelMax;
5153 status = false;
5154 break;
5155 }
5156 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5157 switch (codec_profile.profile) {
5158 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
5159 *eProfile = OMX_VIDEO_HEVCProfileMain;
5160 break;
5161 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
5162 *eProfile = OMX_VIDEO_HEVCProfileMain10;
5163 break;
5164 default:
5165 *eProfile = OMX_VIDEO_HEVCProfileMax;
5166 status = false;
5167 break;
5168 }
5169 if (!status) {
5170 return status;
5171 }
5172
5173 switch (profile_level.level) {
5174 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
5175 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
5176 break;
5177 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
5178 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
5179 break;
5180 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
5181 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
5182 break;
5183 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
5184 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
5185 break;
5186 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
5187 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
5188 break;
5189 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
5190 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
5191 break;
5192 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
5193 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
5194 break;
5195 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
5196 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
5197 break;
5198 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
5199 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
5200 break;
5201 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
5202 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
5203 break;
5204 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
5205 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
5206 break;
5207 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
5208 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
5209 break;
5210 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
5211 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
5212 break;
5213 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
5214 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
5215 break;
5216 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
5217 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
5218 break;
5219 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
5220 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
5221 break;
5222 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
5223 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
5224 break;
5225 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
5226 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
5227 break;
5228 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
5229 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
5230 break;
5231 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
5232 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
5233 break;
5234 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
5235 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
5236 break;
5237 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
5238 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
5239 break;
5240 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
5241 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
5242 break;
5243 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
5244 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
5245 break;
5246 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
5247 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
5248 break;
5249 default:
5250 *eLevel = OMX_VIDEO_HEVCLevelMax;
5251 status = false;
5252 break;
5253 }
5254 }
5255
5256 return status;
5257 }
5258
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)5259 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
5260 {
5261 OMX_U32 new_profile = 0, new_level = 0;
5262 unsigned const int *profile_tbl = NULL;
5263 OMX_U32 mb_per_frame, mb_per_sec;
5264 bool profile_level_found = false;
5265
5266 DEBUG_PRINT_LOW("Init profile table for respective codec");
5267
5268 //validate the ht,width,fps,bitrate and set the appropriate profile and level
5269 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
5270 if (*eProfile == 0) {
5271 if (!m_profile_set) {
5272 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
5273 } else {
5274 switch (codec_profile.profile) {
5275 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
5276 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
5277 break;
5278 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
5279 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
5280 break;
5281 default:
5282 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5283 return false;
5284 }
5285 }
5286 }
5287
5288 if (*eLevel == 0 && !m_level_set) {
5289 *eLevel = OMX_VIDEO_MPEG4LevelMax;
5290 }
5291
5292 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
5293 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
5294 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
5295 profile_tbl = (unsigned int const *)
5296 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
5297 } else {
5298 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
5299 return false;
5300 }
5301 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
5302 if (*eProfile == 0) {
5303 if (!m_profile_set) {
5304 *eProfile = OMX_VIDEO_AVCProfileBaseline;
5305 } else {
5306 switch (codec_profile.profile) {
5307 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
5308 *eProfile = OMX_VIDEO_AVCProfileBaseline;
5309 break;
5310 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
5311 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
5312 break;
5313 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
5314 *eProfile = OMX_VIDEO_AVCProfileMain;
5315 break;
5316 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
5317 *eProfile = OMX_VIDEO_AVCProfileExtended;
5318 break;
5319 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
5320 *eProfile = OMX_VIDEO_AVCProfileHigh;
5321 break;
5322 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
5323 *eProfile = OMX_VIDEO_AVCProfileHigh10;
5324 break;
5325 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
5326 *eProfile = OMX_VIDEO_AVCProfileHigh422;
5327 break;
5328 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
5329 *eProfile = OMX_VIDEO_AVCProfileHigh444;
5330 break;
5331 default:
5332 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5333 return false;
5334 }
5335 }
5336 }
5337
5338 if (*eLevel == 0 && !m_level_set) {
5339 *eLevel = OMX_VIDEO_AVCLevelMax;
5340 }
5341
5342 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
5343 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
5344 profile_tbl = (unsigned int const *)h264_profile_level_table;
5345 } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
5346 profile_tbl = (unsigned int const *)
5347 (&h264_profile_level_table[H264_HP_START]);
5348 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
5349 profile_tbl = (unsigned int const *)
5350 (&h264_profile_level_table[H264_MP_START]);
5351 } else {
5352 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
5353 return false;
5354 }
5355 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
5356 if (*eProfile == 0) {
5357 if (!m_profile_set) {
5358 *eProfile = OMX_VIDEO_H263ProfileBaseline;
5359 } else {
5360 switch (codec_profile.profile) {
5361 case VEN_PROFILE_H263_BASELINE:
5362 *eProfile = OMX_VIDEO_H263ProfileBaseline;
5363 break;
5364 default:
5365 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
5366 return false;
5367 }
5368 }
5369 }
5370
5371 if (*eLevel == 0 && !m_level_set) {
5372 *eLevel = OMX_VIDEO_H263LevelMax;
5373 }
5374
5375 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
5376 profile_tbl = (unsigned int const *)h263_profile_level_table;
5377 } else {
5378 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
5379 return false;
5380 }
5381 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
5382 if (*eProfile == 0) {
5383 *eProfile = OMX_VIDEO_VP8ProfileMain;
5384 } else {
5385 switch (codec_profile.profile) {
5386 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
5387 *eProfile = OMX_VIDEO_VP8ProfileMain;
5388 break;
5389 default:
5390 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
5391 return false;
5392 }
5393 }
5394 if (*eLevel == 0) {
5395 switch (profile_level.level) {
5396 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
5397 *eLevel = OMX_VIDEO_VP8Level_Version0;
5398 break;
5399 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
5400 *eLevel = OMX_VIDEO_VP8Level_Version1;
5401 break;
5402 default:
5403 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
5404 return false;
5405 }
5406 }
5407 return true;
5408 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
5409 if (*eProfile == 0) {
5410 if (!m_profile_set) {
5411 *eProfile = OMX_VIDEO_HEVCProfileMain;
5412 } else {
5413 switch (codec_profile.profile) {
5414 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
5415 *eProfile = OMX_VIDEO_HEVCProfileMain;
5416 break;
5417 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
5418 *eProfile = OMX_VIDEO_HEVCProfileMain10;
5419 break;
5420 default:
5421 DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
5422 return false;
5423 }
5424 }
5425 }
5426
5427 if (*eLevel == 0 && !m_level_set) {
5428 *eLevel = OMX_VIDEO_HEVCLevelMax;
5429 }
5430
5431 if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
5432 profile_tbl = (unsigned int const *)hevc_profile_level_table;
5433 } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
5434 profile_tbl = (unsigned int const *)
5435 (&hevc_profile_level_table[HEVC_MAIN10_START]);
5436 } else {
5437 DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
5438 return false;
5439 }
5440 } else {
5441 DEBUG_PRINT_ERROR("Invalid codec type");
5442 return false;
5443 }
5444
5445 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
5446 ((m_sVenc_cfg.dvs_width + 15)>> 4);
5447
5448 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
5449 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
5450 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
5451
5452 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
5453 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
5454
5455 {
5456 new_level = profile_level.level;
5457 new_profile = codec_profile.profile;
5458 return true;
5459 }
5460 }
5461
5462 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
5463
5464 bool h264, ltr, hlayers;
5465 unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
5466 h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
5467 ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
5468 hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
5469 ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
5470
5471 /* Hybrid HP reference buffers:
5472 layers = 1, 2 need 1 reference buffer
5473 layers = 3, 4 need 2 reference buffers
5474 layers = 5, 6 need 3 reference buffers
5475 */
5476
5477 if(hier_layers.hier_mode == HIER_P_HYBRID)
5478 hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
5479
5480 do {
5481 if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
5482 if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
5483 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
5484 if (h264 && (ltr || hlayers || hybridp)) {
5485 // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
5486 new_level = (int)profile_tbl[3];
5487 new_profile = (int)profile_tbl[4];
5488 profile_level_found = true;
5489 DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
5490 ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
5491 MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
5492 break;
5493 } else {
5494 new_level = (int)profile_tbl[3];
5495 new_profile = (int)profile_tbl[4];
5496 profile_level_found = true;
5497 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
5498 break;
5499 }
5500 }
5501 }
5502 }
5503 profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
5504 } while (profile_tbl[0] != 0);
5505
5506 if (profile_level_found != true) {
5507 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
5508 return false;
5509 }
5510
5511 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
5512 || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
5513 || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
5514 *eLevel = new_level;
5515 }
5516
5517 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
5518 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
5519
5520 return true;
5521 }
5522 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)5523 bool venc_dev::venc_set_meta_mode(bool mode)
5524 {
5525 metadatamode = mode;
5526 return true;
5527 }
5528 #endif
5529
venc_is_video_session_supported(unsigned long width,unsigned long height)5530 bool venc_dev::venc_is_video_session_supported(unsigned long width,
5531 unsigned long height)
5532 {
5533 if ((width * height < capability.min_width * capability.min_height) ||
5534 (width * height > capability.max_width * capability.max_height)) {
5535 DEBUG_PRINT_ERROR(
5536 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
5537 width, height, capability.min_width, capability.min_height,
5538 capability.max_width, capability.max_height);
5539 return false;
5540 }
5541
5542 DEBUG_PRINT_LOW("video session supported");
5543 return true;
5544 }
5545