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