1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2014, 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 #endif
48
49 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
50 #define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
51
52 #define MPEG4_SP_START 0
53 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
54 #define H263_BP_START 0
55 #define H264_BP_START 0
56 #define H264_HP_START (H264_BP_START + 17)
57 #define H264_MP_START (H264_BP_START + 34)
58 #define POLL_TIMEOUT 1000
59 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
60
61 #define SZ_4K 0x1000
62 #define SZ_1M 0x100000
63
64 /* MPEG4 profile and level table*/
65 static const unsigned int mpeg4_profile_level_table[][5]= {
66 /*max mb per frame, max mb per sec, max bitrate, level, profile*/
67 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
68 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
69 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
70 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
71 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
72 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
73 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
74 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
75 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
76 {0,0,0,0,0},
77
78 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
79 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
80 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
81 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
82 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
83 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
84 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
85 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
86 {0,0,0,0,0},
87 };
88
89 /* H264 profile and level table*/
90 static const unsigned int h264_profile_level_table[][5]= {
91 /*max mb per frame, max mb per sec, max bitrate, level, profile*/
92 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
93 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
94 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
95 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
96 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
97 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
98 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
99 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
100 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
101 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
102 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
103 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
104 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline},
105 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline},
106 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline},
107 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline},
108 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
109 {0,0,0,0,0},
110
111 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
112 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
113 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
114 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
115 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
116 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
117 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
118 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
119 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
120 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
121 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
122 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
123 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh},
124 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh},
125 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh},
126 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh},
127 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh},
128 {0,0,0,0,0},
129
130 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
131 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
132 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
133 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
134 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
135 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
136 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
137 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
138 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
139 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
140 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
141 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
142 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain},
143 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain},
144 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain},
145 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain},
146 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
147 {0,0,0,0,0}
148
149 };
150
151 /* H263 profile and level table*/
152 static const unsigned int h263_profile_level_table[][5]= {
153 /*max mb per frame, max mb per sec, max bitrate, level, profile*/
154 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
155 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
156 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
157 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
158 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
159 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
160 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
161 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
162 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
163 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
164 {0,0,0,0,0}
165 };
166
167 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
168 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
169
170 #define BUFFER_LOG_LOC "/data/misc/media"
171
172 //constructor
venc_dev(class omx_venc * venc_class)173 venc_dev::venc_dev(class omx_venc *venc_class)
174 {
175 //nothing to do
176 int i = 0;
177 venc_handle = venc_class;
178 etb = ebd = ftb = fbd = 0;
179
180 for (i = 0; i < MAX_PORT; i++)
181 streaming[i] = false;
182
183 stopped = 1;
184 paused = false;
185 async_thread_created = false;
186 color_format = 0;
187 pthread_mutex_init(&pause_resume_mlock, NULL);
188 pthread_cond_init(&pause_resume_cond, NULL);
189 memset(&extradata_info, 0, sizeof(extradata_info));
190 memset(&idrperiod, 0, sizeof(idrperiod));
191 memset(&multislice, 0, sizeof(multislice));
192 memset (&slice_mode, 0 , sizeof(slice_mode));
193 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
194 memset(&rate_ctrl, 0, sizeof(rate_ctrl));
195 memset(&bitrate, 0, sizeof(bitrate));
196 memset(&intra_period, 0, sizeof(intra_period));
197 memset(&codec_profile, 0, sizeof(codec_profile));
198 memset(&set_param, 0, sizeof(set_param));
199 memset(&time_inc, 0, sizeof(time_inc));
200 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
201 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
202 memset(&session_qp, 0, sizeof(session_qp));
203 memset(&entropy, 0, sizeof(entropy));
204 memset(&dbkfilter, 0, sizeof(dbkfilter));
205 memset(&intra_refresh, 0, sizeof(intra_refresh));
206 memset(&hec, 0, sizeof(hec));
207 memset(&voptimecfg, 0, sizeof(voptimecfg));
208 memset(&capability, 0, sizeof(capability));
209 memset(&m_debug,0,sizeof(m_debug));
210 memset(&hier_p_layers,0,sizeof(hier_p_layers));
211 memset(&display_info,0,sizeof(display_info));
212 is_searchrange_set = false;
213 enable_mv_narrow_searchrange = false;
214
215 char property_value[PROPERTY_VALUE_MAX] = {0};
216 property_get("vidc.enc.log.in", property_value, "0");
217 m_debug.in_buffer_log = atoi(property_value);
218
219 property_get("vidc.enc.log.out", property_value, "0");
220 m_debug.out_buffer_log = atoi(property_value);
221
222 property_get("vidc.enc.log.extradata", property_value, "0");
223 m_debug.extradata_log = atoi(property_value);
224
225 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
226 "%s", BUFFER_LOG_LOC);
227 }
228
~venc_dev()229 venc_dev::~venc_dev()
230 {
231 //nothing to do
232 }
233
async_venc_message_thread(void * input)234 void* venc_dev::async_venc_message_thread (void *input)
235 {
236 struct venc_msg venc_msg;
237 omx_video* omx_venc_base = NULL;
238 omx_venc *omx = reinterpret_cast<omx_venc*>(input);
239 omx_venc_base = reinterpret_cast<omx_video*>(input);
240 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
241
242 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
243 struct v4l2_plane plane[VIDEO_MAX_PLANES];
244 struct pollfd pfd;
245 struct v4l2_buffer v4l2_buf;
246 struct v4l2_event dqevent;
247 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
248 pfd.fd = omx->handle->m_nDriver_fd;
249 int error_code = 0,rc=0;
250
251 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
252
253 while (1) {
254 pthread_mutex_lock(&omx->handle->pause_resume_mlock);
255
256 if (omx->handle->paused) {
257 venc_msg.msgcode = VEN_MSG_PAUSE;
258 venc_msg.statuscode = VEN_S_SUCCESS;
259
260 if (omx->async_message_process(input, &venc_msg) < 0) {
261 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
262 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
263 break;
264 }
265
266 /* Block here until the IL client resumes us again */
267 pthread_cond_wait(&omx->handle->pause_resume_cond,
268 &omx->handle->pause_resume_mlock);
269
270 venc_msg.msgcode = VEN_MSG_RESUME;
271 venc_msg.statuscode = VEN_S_SUCCESS;
272
273 if (omx->async_message_process(input, &venc_msg) < 0) {
274 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
275 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
276 break;
277 }
278 }
279
280 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
281
282 rc = poll(&pfd, 1, POLL_TIMEOUT);
283
284 if (!rc) {
285 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
286 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
287 continue;
288 } else if (rc < 0) {
289 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
290 break;
291 }
292
293 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
294 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
295 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
296 v4l2_buf.length = omx->handle->num_planes;
297 v4l2_buf.m.planes = plane;
298
299 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
300 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
301 venc_msg.statuscode=VEN_S_SUCCESS;
302 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
303 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
304 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
305 venc_msg.buf.flags = 0;
306 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
307 venc_msg.buf.clientdata=(void*)omxhdr;
308 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
309
310 /* TODO: ideally report other types of frames as well
311 * for now it doesn't look like IL client cares about
312 * other types
313 */
314 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
315 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
316
317 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
318 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
319
320 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
321 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
322
323 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
324 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
325
326 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
327 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
328
329 if (omxhdr->nFilledLen)
330 venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
331
332 omx->handle->fbd++;
333
334 if (omx->async_message_process(input,&venc_msg) < 0) {
335 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
336 break;
337 }
338 }
339 }
340
341 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
342 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
343 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
344 v4l2_buf.m.planes = plane;
345 v4l2_buf.length = 1;
346
347 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
348 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
349 venc_msg.statuscode=VEN_S_SUCCESS;
350 omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
351 venc_msg.buf.clientdata=(void*)omxhdr;
352 omx->handle->ebd++;
353
354 if (omx->async_message_process(input,&venc_msg) < 0) {
355 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
356 break;
357 }
358 }
359 }
360
361 if (pfd.revents & POLLPRI) {
362 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
363
364 if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
365 DEBUG_PRINT_HIGH("CLOSE DONE");
366 break;
367 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
368 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
369 venc_msg.statuscode = VEN_S_SUCCESS;
370
371 if (omx->async_message_process(input,&venc_msg) < 0) {
372 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
373 break;
374 }
375
376 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
377 venc_msg.statuscode = VEN_S_SUCCESS;
378
379 if (omx->async_message_process(input,&venc_msg) < 0) {
380 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
381 break;
382 }
383 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
384 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
385 venc_msg.msgcode = VEN_MSG_INDICATION;
386 venc_msg.statuscode=VEN_S_EFAIL;
387
388 if (omx->async_message_process(input,&venc_msg) < 0) {
389 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
390 break;
391 }
392 }
393 }
394 }
395
396 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
397 return NULL;
398 }
399
400 static const int event_type[] = {
401 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
402 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
403 V4L2_EVENT_MSM_VIDC_SYS_ERROR
404 };
405
subscribe_to_events(int fd)406 static OMX_ERRORTYPE subscribe_to_events(int fd)
407 {
408 OMX_ERRORTYPE eRet = OMX_ErrorNone;
409 struct v4l2_event_subscription sub;
410 int array_sz = sizeof(event_type)/sizeof(int);
411 int i,rc;
412 memset(&sub, 0, sizeof(sub));
413
414 if (fd < 0) {
415 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
416 return OMX_ErrorBadParameter;
417 }
418
419 for (i = 0; i < array_sz; ++i) {
420 memset(&sub, 0, sizeof(sub));
421 sub.type = event_type[i];
422 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
423
424 if (rc) {
425 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
426 break;
427 }
428 }
429
430 if (i < array_sz) {
431 for (--i; i >=0 ; i--) {
432 memset(&sub, 0, sizeof(sub));
433 sub.type = event_type[i];
434 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
435
436 if (rc)
437 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
438 }
439
440 eRet = OMX_ErrorNotImplemented;
441 }
442
443 return eRet;
444 }
445
append_mbi_extradata(void * dst,struct msm_vidc_extradata_header * src)446 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
447 {
448 OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
449
450 if (!dst || !src)
451 return 0;
452
453 /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
454 * targets, since the payload format will be different */
455 mbi->nFormat = 1;
456 mbi->nDataSize = src->data_size;
457 memcpy(&mbi->data, &src->data, src->data_size);
458
459 return mbi->nDataSize + sizeof(*mbi);
460 }
461
handle_extradata(void * buffer,int index)462 bool venc_dev::handle_extradata(void *buffer, int index)
463 {
464 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
465 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
466
467 if (!extradata_info.uaddr) {
468 DEBUG_PRINT_ERROR("Extradata buffers not allocated");
469 return false;
470 }
471
472 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
473 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
474
475 if (extradata_info.buffer_size >
476 p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
477 DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
478 p_extra = NULL;
479 return false;
480 } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
481 /* A lot of the code below assumes this condition, so error out if it's not met */
482 DEBUG_PRINT_ERROR("Extradata ABI mismatch");
483 return false;
484 }
485
486 struct msm_vidc_extradata_header *p_extradata = NULL;
487 do {
488 p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
489 ((char *)p_extradata) + p_extradata->size :
490 extradata_info.uaddr + index * extradata_info.buffer_size);
491
492 switch (p_extradata->type) {
493 case MSM_VIDC_EXTRADATA_METADATA_MBI:
494 {
495 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
496 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
497 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
498 p_extra->nPortIndex = OMX_DirOutput;
499 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
500 p_extra->nDataSize = payloadSize;
501 break;
502 }
503 case MSM_VIDC_EXTRADATA_NONE:
504 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
505 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
506 p_extra->nPortIndex = OMX_DirOutput;
507 p_extra->eType = OMX_ExtraDataNone;
508 p_extra->nDataSize = 0;
509 break;
510 default:
511 /* No idea what this stuff is, just skip over it */
512 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
513 p_extradata->type);
514 continue;
515 }
516
517 p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
518 } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
519
520 /* Just for debugging: Traverse the list of extra datas and spit it out onto log */
521 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
522 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
523 while(p_extra->eType != OMX_ExtraDataNone)
524 {
525 DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
526 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
527 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
528
529 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
530 p_extra->nSize);
531 }
532
533 return true;
534 }
535
venc_set_format(int format)536 int venc_dev::venc_set_format(int format)
537 {
538 int rc = true;
539
540 if (format)
541 color_format = format;
542 else {
543 color_format = 0;
544 rc = false;
545 }
546
547 return rc;
548 }
549
allocate_extradata()550 OMX_ERRORTYPE venc_dev::allocate_extradata()
551 {
552 if (extradata_info.allocated) {
553 DEBUG_PRINT_ERROR("Extradata already allocated!");
554 return OMX_ErrorNone;
555 }
556
557 #ifdef USE_ION
558
559 if (extradata_info.buffer_size) {
560 if (extradata_info.ion.ion_alloc_data.handle) {
561 munmap((void *)extradata_info.uaddr, extradata_info.size);
562 close(extradata_info.ion.fd_ion_data.fd);
563 venc_handle->free_ion_memory(&extradata_info.ion);
564 }
565
566 extradata_info.size = ALIGN(extradata_info.size, SZ_4K);
567
568 extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory(
569 extradata_info.size,
570 &extradata_info.ion.ion_alloc_data,
571 &extradata_info.ion.fd_ion_data, 0);
572
573 if (extradata_info.ion.ion_device_fd < 0) {
574 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
575 return OMX_ErrorInsufficientResources;
576 }
577
578 extradata_info.uaddr = (char *)mmap(NULL,
579 extradata_info.size,
580 PROT_READ|PROT_WRITE, MAP_SHARED,
581 extradata_info.ion.fd_ion_data.fd , 0);
582
583 if (extradata_info.uaddr == MAP_FAILED) {
584 DEBUG_PRINT_ERROR("Failed to map extradata memory");
585 close(extradata_info.ion.fd_ion_data.fd);
586 venc_handle->free_ion_memory(&extradata_info.ion);
587 return OMX_ErrorInsufficientResources;
588 }
589 }
590
591 #endif
592 extradata_info.allocated = 1;
593 return OMX_ErrorNone;
594 }
595
free_extradata()596 void venc_dev::free_extradata()
597 {
598 #ifdef USE_ION
599
600 if (extradata_info.uaddr) {
601 munmap((void *)extradata_info.uaddr, extradata_info.size);
602 close(extradata_info.ion.fd_ion_data.fd);
603 venc_handle->free_ion_memory(&extradata_info.ion);
604 }
605
606 memset(&extradata_info, 0, sizeof(extradata_info));
607 #endif
608 }
609
venc_get_output_log_flag()610 bool venc_dev::venc_get_output_log_flag()
611 {
612 return (m_debug.out_buffer_log == 1);
613 }
614
venc_output_log_buffers(const char * buffer_addr,int buffer_len)615 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
616 {
617 if (!m_debug.outfile) {
618 int size = 0;
619 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
620 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
621 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
622 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
623 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
624 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
625 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
626 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
627 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
628 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
629 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
630 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
631 }
632 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
633 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
634 m_debug.outfile_name, size);
635 }
636 m_debug.outfile = fopen(m_debug.outfile_name, "ab");
637 if (!m_debug.outfile) {
638 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
639 m_debug.outfile_name, errno);
640 m_debug.outfile_name[0] = '\0';
641 return -1;
642 }
643 }
644 if (m_debug.outfile && buffer_len) {
645 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
646 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
647 }
648 return 0;
649 }
650
venc_extradata_log_buffers(char * buffer_addr)651 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
652 {
653 if (!m_debug.extradatafile && m_debug.extradata_log) {
654 int size = 0;
655 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
656 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
657 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
658 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
659 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
660 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
661 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
662 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
663 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
664 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
665 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
666 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
667 }
668 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
669 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
670 m_debug.extradatafile_name, size);
671 }
672
673 m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
674 if (!m_debug.extradatafile) {
675 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
676 m_debug.extradatafile_name, errno);
677 m_debug.extradatafile_name[0] = '\0';
678 return -1;
679 }
680 }
681
682 if (m_debug.extradatafile) {
683 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
684 do {
685 p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
686 ((char *)p_extra) + p_extra->nSize);
687 fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
688 } while (p_extra->eType != OMX_ExtraDataNone);
689 }
690 return 0;
691 }
692
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset)693 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) {
694 if (!m_debug.infile) {
695 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
696 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
697 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
698 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
699 m_debug.infile_name, size);
700 }
701 m_debug.infile = fopen (m_debug.infile_name, "ab");
702 if (!m_debug.infile) {
703 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
704 m_debug.infile_name[0] = '\0';
705 return -1;
706 }
707 }
708 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
709 unsigned long i, msize;
710 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
711 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
712 unsigned char *pvirt,*ptemp;
713
714 char *temp = (char *)pbuffer->pBuffer;
715
716 msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
717 if (metadatamode == 1) {
718 pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
719 if (pvirt) {
720 ptemp = pvirt;
721 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
722 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
723 ptemp += stride;
724 }
725 ptemp = pvirt + (stride * scanlines);
726 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
727 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
728 ptemp += stride;
729 }
730 munmap(pvirt, msize);
731 } else if (pvirt == MAP_FAILED) {
732 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
733 return -1;
734 }
735 } else {
736 for (i = 0; i < m_sVenc_cfg.input_height; i++) {
737 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
738 temp += stride;
739 }
740
741 temp = (char *)pbuffer->pBuffer + (stride * scanlines);
742
743 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
744 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
745 temp += stride;
746 }
747 }
748 }
749 return 0;
750 }
751
venc_open(OMX_U32 codec)752 bool venc_dev::venc_open(OMX_U32 codec)
753 {
754 int r;
755 unsigned int alignment = 0,buffer_size = 0, temp =0;
756 struct v4l2_control control;
757 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc";
758
759 char platform_name[PROPERTY_VALUE_MAX];
760 property_get("ro.board.platform", platform_name, "0");
761
762 if (!strncmp(platform_name, "msm8610", 7)) {
763 device_name = (OMX_STRING)"/dev/video/q6_enc";
764 }
765 if (!strncmp(platform_name, "msm8916", 7)) {
766 enable_mv_narrow_searchrange = true;
767 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
768 ISurfaceComposer::eDisplayIdMain));
769 SurfaceComposerClient::getDisplayInfo(display, &display_info);
770 DEBUG_PRINT_LOW("Display panel resolution %dX%d",
771 display_info.w, display_info.h);
772 }
773 m_nDriver_fd = open (device_name, O_RDWR);
774
775 if (m_nDriver_fd == 0) {
776 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
777 m_nDriver_fd = open (device_name, O_RDWR);
778 }
779
780 if ((int)m_nDriver_fd < 0) {
781 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
782 return false;
783 }
784
785 DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
786 // set the basic configuration of the video encoder driver
787 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
788 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
789 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
790 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
791 m_sVenc_cfg.fps_num = 30;
792 m_sVenc_cfg.fps_den = 1;
793 m_sVenc_cfg.targetbitrate = 64000;
794 m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
795 m_codec = codec;
796
797 if (codec == OMX_VIDEO_CodingMPEG4) {
798 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
799 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
800 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
801 session_qp_range.minqp = 1;
802 session_qp_range.maxqp = 31;
803 } else if (codec == OMX_VIDEO_CodingH263) {
804 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
805 codec_profile.profile = VEN_PROFILE_H263_BASELINE;
806 profile_level.level = VEN_LEVEL_H263_20;
807 session_qp_range.minqp = 1;
808 session_qp_range.maxqp = 31;
809 } else if (codec == OMX_VIDEO_CodingAVC) {
810 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
811 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
812 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
813 session_qp_range.minqp = 1;
814 session_qp_range.maxqp = 51;
815 } else if (codec == OMX_VIDEO_CodingVP8) {
816 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
817 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
818 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
819 session_qp_range.minqp = 1;
820 session_qp_range.maxqp = 128;
821 }
822 session_qp_values.minqp = session_qp_range.minqp;
823 session_qp_values.maxqp = session_qp_range.maxqp;
824
825 int ret;
826 ret = subscribe_to_events(m_nDriver_fd);
827
828 if (ret) {
829 DEBUG_PRINT_ERROR("Subscribe Event Failed");
830 return false;
831 }
832
833 struct v4l2_capability cap;
834
835 struct v4l2_fmtdesc fdesc;
836
837 struct v4l2_format fmt;
838
839 struct v4l2_requestbuffers bufreq;
840
841 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
842
843 if (ret) {
844 DEBUG_PRINT_ERROR("Failed to query capabilities");
845 } else {
846 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
847 " version = %d, capabilities = %x", cap.driver, cap.card,
848 cap.bus_info, cap.version, cap.capabilities);
849 }
850
851 ret=0;
852 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
853 fdesc.index=0;
854
855 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
856 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
857 fdesc.pixelformat, fdesc.flags);
858 fdesc.index++;
859 }
860
861 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
862 fdesc.index=0;
863
864 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
865 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
866 fdesc.pixelformat, fdesc.flags);
867 fdesc.index++;
868 }
869
870 if (venc_handle->is_secure_session()) {
871 m_sOutput_buff_property.alignment = SZ_1M;
872 m_sInput_buff_property.alignment = SZ_1M;
873 } else {
874 m_sOutput_buff_property.alignment = SZ_4K;
875 m_sInput_buff_property.alignment = SZ_4K;
876 }
877 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
878 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
879 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
880 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
881
882 /*TODO: Return values not handled properly in this function anywhere.
883 * Need to handle those.*/
884 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
885
886 if (ret) {
887 DEBUG_PRINT_ERROR("Failed to set format on capture port");
888 return false;
889 }
890
891 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
892
893 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
894 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
895 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
896 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
897
898 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
899 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
900
901 bufreq.memory = V4L2_MEMORY_USERPTR;
902 bufreq.count = 2;
903
904 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
905 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
906 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
907
908 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
909 bufreq.count = 2;
910 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
911 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
912
913 if(venc_handle->is_secure_session()) {
914 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
915 control.value = 1;
916 DEBUG_PRINT_HIGH("ioctl: open secure device");
917 ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
918 if (ret) {
919 DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
920 return false;
921 }
922 }
923
924 resume_in_stopped = 0;
925 metadatamode = 0;
926
927 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
928 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
929
930 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
931
932 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
933 DEBUG_PRINT_ERROR("Failed to set control");
934
935 struct v4l2_frmsizeenum frmsize;
936
937 //Get the hardware capabilities
938 memset((void *)&frmsize,0,sizeof(frmsize));
939 frmsize.index = 0;
940 frmsize.pixel_format = m_sVenc_cfg.codectype;
941 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
942
943 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
944 DEBUG_PRINT_ERROR("Failed to get framesizes");
945 return false;
946 }
947
948 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
949 capability.min_width = frmsize.stepwise.min_width;
950 capability.max_width = frmsize.stepwise.max_width;
951 capability.min_height = frmsize.stepwise.min_height;
952 capability.max_height = frmsize.stepwise.max_height;
953 }
954 //Initialize non-default parameters
955 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
956 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
957 control.value = 0x7fffffff;
958 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
959 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
960 }
961
962 return true;
963 }
964
965
unsubscribe_to_events(int fd)966 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
967 {
968 OMX_ERRORTYPE eRet = OMX_ErrorNone;
969 struct v4l2_event_subscription sub;
970 int array_sz = sizeof(event_type)/sizeof(int);
971 int i,rc;
972
973 if (fd < 0) {
974 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
975 return OMX_ErrorBadParameter;
976 }
977
978 for (i = 0; i < array_sz; ++i) {
979 memset(&sub, 0, sizeof(sub));
980 sub.type = event_type[i];
981 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
982
983 if (rc) {
984 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
985 break;
986 }
987 }
988
989 return eRet;
990 }
991
venc_close()992 void venc_dev::venc_close()
993 {
994 struct v4l2_encoder_cmd enc;
995 DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
996
997 if ((int)m_nDriver_fd >= 0) {
998 enc.cmd = V4L2_ENC_CMD_STOP;
999 ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
1000 DEBUG_PRINT_HIGH("venc_close E");
1001
1002 if (async_thread_created)
1003 pthread_join(m_tid,NULL);
1004
1005 DEBUG_PRINT_HIGH("venc_close X");
1006 unsubscribe_to_events(m_nDriver_fd);
1007 close(m_nDriver_fd);
1008 m_nDriver_fd = -1;
1009 }
1010
1011 if (m_debug.infile) {
1012 fclose(m_debug.infile);
1013 m_debug.infile = NULL;
1014 }
1015
1016 if (m_debug.outfile) {
1017 fclose(m_debug.outfile);
1018 m_debug.outfile = NULL;
1019 }
1020
1021 if (m_debug.extradatafile) {
1022 fclose(m_debug.extradatafile);
1023 m_debug.extradatafile = NULL;
1024 }
1025 }
1026
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1027 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1028 OMX_U32 *actual_buff_count,
1029 OMX_U32 *buff_size,
1030 OMX_U32 port)
1031 {
1032 (void)min_buff_count, (void)buff_size;
1033 unsigned long temp_count = 0;
1034
1035 if (port == 0) {
1036 if (*actual_buff_count > m_sInput_buff_property.mincount) {
1037 temp_count = m_sInput_buff_property.actualcount;
1038 m_sInput_buff_property.actualcount = *actual_buff_count;
1039 DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1040 }
1041 } else {
1042 if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1043 temp_count = m_sOutput_buff_property.actualcount;
1044 m_sOutput_buff_property.actualcount = *actual_buff_count;
1045 DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1046 }
1047 }
1048
1049 return true;
1050
1051 }
1052
venc_loaded_start()1053 bool venc_dev::venc_loaded_start()
1054 {
1055 return true;
1056 }
1057
venc_loaded_stop()1058 bool venc_dev::venc_loaded_stop()
1059 {
1060 return true;
1061 }
1062
venc_loaded_start_done()1063 bool venc_dev::venc_loaded_start_done()
1064 {
1065 return true;
1066 }
1067
venc_loaded_stop_done()1068 bool venc_dev::venc_loaded_stop_done()
1069 {
1070 return true;
1071 }
1072
venc_get_seq_hdr(void * buffer,unsigned buffer_size,OMX_U32 * header_len)1073 bool venc_dev::venc_get_seq_hdr(void *buffer,
1074 unsigned buffer_size, OMX_U32 *header_len)
1075 {
1076 (void) buffer, (void) buffer_size, (void) header_len;
1077 return true;
1078 }
1079
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1080 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1081 OMX_U32 *actual_buff_count,
1082 OMX_U32 *buff_size,
1083 OMX_U32 port)
1084 {
1085 struct v4l2_format fmt;
1086 struct v4l2_requestbuffers bufreq;
1087 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1088 int ret;
1089
1090 if (port == 0) {
1091 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1092 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1093 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1094 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1095 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1096 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1097 bufreq.memory = V4L2_MEMORY_USERPTR;
1098
1099 if (*actual_buff_count)
1100 bufreq.count = *actual_buff_count;
1101 else
1102 bufreq.count = 2;
1103
1104 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1105 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1106
1107 if (ret) {
1108 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1109 return false;
1110 }
1111
1112 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1113 *min_buff_count = m_sInput_buff_property.mincount;
1114 *actual_buff_count = m_sInput_buff_property.actualcount;
1115 #ifdef USE_ION
1116 // For ION memory allocations of the allocated buffer size
1117 // must be 4k aligned, hence aligning the input buffer
1118 // size to 4k.
1119 m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1120 #endif
1121 *buff_size = m_sInput_buff_property.datasize;
1122 } else {
1123 int extra_idx = 0;
1124 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1125 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1126 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1127 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1128
1129 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1130 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1131 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1132 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1133 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1134 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1135
1136 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1137 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1138 bufreq.memory = V4L2_MEMORY_USERPTR;
1139
1140 if (*actual_buff_count)
1141 bufreq.count = *actual_buff_count;
1142 else
1143 bufreq.count = 2;
1144
1145 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1146 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1147
1148 if (ret) {
1149 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
1150 return false;
1151 }
1152
1153 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1154 *min_buff_count = m_sOutput_buff_property.mincount;
1155 *actual_buff_count = m_sOutput_buff_property.actualcount;
1156 *buff_size = m_sOutput_buff_property.datasize;
1157 num_planes = fmt.fmt.pix_mp.num_planes;
1158 extra_idx = EXTRADATA_IDX(num_planes);
1159
1160 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1161 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1162 } else if (extra_idx >= VIDEO_MAX_PLANES) {
1163 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
1164 return OMX_ErrorBadParameter;
1165 }
1166
1167 extradata_info.buffer_size = extra_data_size;
1168 extradata_info.count = m_sOutput_buff_property.actualcount;
1169 extradata_info.size = extradata_info.buffer_size * extradata_info.count;
1170 }
1171
1172 return true;
1173 }
1174
venc_set_param(void * paramData,OMX_INDEXTYPE index)1175 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
1176 {
1177 DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
1178 struct v4l2_format fmt;
1179 struct v4l2_requestbuffers bufreq;
1180 int ret;
1181
1182 switch ((int)index) {
1183 case OMX_IndexParamPortDefinition:
1184 {
1185 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1186 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1187 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
1188
1189 if (portDefn->nPortIndex == PORT_INDEX_IN) {
1190 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
1191 return false;
1192 }
1193
1194 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
1195 return false;
1196 }
1197 if ((display_info.w * display_info.h) > (OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
1198 && enable_mv_narrow_searchrange &&
1199 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
1200 (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
1201 if (venc_set_searchrange() == false) {
1202 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1203 }
1204 }
1205 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
1206 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
1207 DEBUG_PRINT_LOW("Basic parameter has changed");
1208 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
1209 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
1210 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1211 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1212 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1213 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
1214
1215 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1216 DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
1217 return false;
1218 }
1219
1220 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1221 bufreq.memory = V4L2_MEMORY_USERPTR;
1222 bufreq.count = portDefn->nBufferCountActual;
1223 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1224
1225 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1226 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
1227 return false;
1228 }
1229
1230 if (bufreq.count == portDefn->nBufferCountActual)
1231 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1232
1233 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
1234 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
1235 }
1236
1237 DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
1238 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
1239 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
1240 m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
1241 m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
1242 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1243 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1244 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1245 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1246
1247 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
1248 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
1249 return false;
1250 }
1251
1252 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1253
1254 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
1255 return false;
1256 }
1257
1258 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1259 bufreq.memory = V4L2_MEMORY_USERPTR;
1260 bufreq.count = portDefn->nBufferCountActual;
1261 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1262
1263 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
1264 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
1265 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
1266 return false;
1267 }
1268
1269 if (bufreq.count == portDefn->nBufferCountActual)
1270 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1271
1272 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
1273 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
1274
1275 if (num_planes > 1)
1276 extradata_info.count = m_sOutput_buff_property.actualcount;
1277
1278 DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
1279 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
1280 } else {
1281 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
1282 }
1283
1284 break;
1285 }
1286 case OMX_IndexParamVideoPortFormat:
1287 {
1288 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
1289 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1290 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
1291
1292 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1293 if (!venc_set_color_format(portFmt->eColorFormat)) {
1294 return false;
1295 }
1296 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1297 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
1298 return false;
1299 }
1300 } else {
1301 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
1302 }
1303
1304 break;
1305 }
1306 case OMX_IndexParamVideoBitrate:
1307 {
1308 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
1309 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1310 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
1311
1312 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1313 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
1314 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
1315 return false;
1316 }
1317
1318 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
1319 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
1320 return false;
1321 }
1322 } else {
1323 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
1324 }
1325
1326 break;
1327 }
1328 case OMX_IndexParamVideoMpeg4:
1329 {
1330 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
1331 OMX_U32 bFrames = 0;
1332
1333 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1334 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
1335
1336 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1337 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
1338 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
1339 return false;
1340 }
1341
1342 m_profile_set = false;
1343 m_level_set = false;
1344
1345 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1346 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1347 return false;
1348 } else {
1349 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
1350 if (pParam->nBFrames) {
1351 bFrames = pParam->nBFrames;
1352 }
1353 } else {
1354 if (pParam->nBFrames) {
1355 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1356 bFrames = 0;
1357 }
1358 }
1359 }
1360
1361 if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
1362 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1363 return false;
1364 }
1365
1366 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
1367 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
1368 return false;
1369 }
1370 } else {
1371 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
1372 }
1373
1374 break;
1375 }
1376 case OMX_IndexParamVideoH263:
1377 {
1378 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1379 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
1380 OMX_U32 bFrames = 0;
1381
1382 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1383 m_profile_set = false;
1384 m_level_set = false;
1385
1386 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1387 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
1388 return false;
1389 }
1390
1391 if (pParam->nBFrames)
1392 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
1393
1394 if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
1395 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1396 return false;
1397 }
1398 } else {
1399 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
1400 }
1401
1402 break;
1403 }
1404 case OMX_IndexParamVideoAvc:
1405 {
1406 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
1407 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1408 OMX_U32 bFrames = 0;
1409
1410 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1411 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
1412 pParam->eProfile,pParam->eLevel);
1413
1414 m_profile_set = false;
1415 m_level_set = false;
1416
1417 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
1418 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1419 pParam->eProfile, pParam->eLevel);
1420 return false;
1421 } else {
1422 if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
1423 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
1424 if (pParam->nBFrames) {
1425 bFrames = pParam->nBFrames;
1426 }
1427 } else {
1428 if (pParam->nBFrames) {
1429 DEBUG_PRINT_ERROR("Warning: B frames not supported");
1430 bFrames = 0;
1431 }
1432 }
1433 }
1434
1435 if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
1436 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1437 return false;
1438 }
1439
1440 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
1441 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
1442 return false;
1443 }
1444
1445 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
1446 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
1447 return false;
1448 }
1449
1450 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
1451 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
1452 return false;
1453 }
1454 } else {
1455 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
1456 }
1457
1458 //TBD, lot of other variables to be updated, yet to decide
1459 break;
1460 }
1461 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1462 {
1463 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
1464 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1465 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
1466 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
1467 pParam->eProfile, pParam->eLevel);
1468 return false;
1469 }
1470
1471 if(!venc_set_ltrmode(1, 1)) {
1472 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
1473 return false;
1474 }
1475
1476 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1477 // Disable hier-p if ltr is enabled.
1478 if (m_codec == OMX_VIDEO_CodingVP8) {
1479 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
1480 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
1481 DEBUG_PRINT_ERROR("Disabling Hier P count failed");
1482 }
1483 }
1484
1485 break;
1486 }
1487 case OMX_IndexParamVideoIntraRefresh:
1488 {
1489 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
1490 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
1491 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
1492
1493 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1494 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
1495 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1496 return false;
1497 }
1498 } else {
1499 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
1500 }
1501
1502 break;
1503 }
1504 case OMX_IndexParamVideoErrorCorrection:
1505 {
1506 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
1507 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
1508 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
1509
1510 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1511 if (venc_set_error_resilience(error_resilience) == false) {
1512 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
1513 return false;
1514 }
1515 } else {
1516 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
1517 }
1518
1519 break;
1520 }
1521 case OMX_IndexParamVideoProfileLevelCurrent:
1522 {
1523 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
1524 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
1525 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
1526
1527 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1528 m_profile_set = false;
1529 m_level_set = false;
1530
1531 if (!venc_set_profile_level (profile_level->eProfile,
1532 profile_level->eLevel)) {
1533 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
1534 return false;
1535 }
1536 } else {
1537 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
1538 }
1539
1540 break;
1541 }
1542 case OMX_IndexParamVideoQuantization:
1543 {
1544 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
1545 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
1546 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
1547 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1548 if (venc_set_session_qp (session_qp->nQpI,
1549 session_qp->nQpP,
1550 session_qp->nQpB) == false) {
1551 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
1552 return false;
1553 }
1554 } else {
1555 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
1556 }
1557
1558 break;
1559 }
1560 case QOMX_IndexParamVideoInitialQp:
1561 {
1562 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
1563 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
1564 if (initqp->bEnableInitQp) {
1565 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
1566 if(venc_enable_initial_qp(initqp) == false) {
1567 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
1568 return OMX_ErrorUnsupportedSetting;
1569 }
1570 } else
1571 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
1572 break;
1573 }
1574 case OMX_QcomIndexParamVideoQPRange:
1575 {
1576 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
1577 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
1578 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
1579
1580 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1581 if(venc_set_session_qp_range (session_qp_range->minQP,
1582 session_qp_range->maxQP) == false) {
1583 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
1584 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
1585 return false;
1586 } else {
1587 session_qp_values.minqp = session_qp_range->minQP;
1588 session_qp_values.maxqp = session_qp_range->maxQP;
1589 }
1590 } else {
1591 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
1592 }
1593
1594 break;
1595 }
1596 case OMX_QcomIndexEnableSliceDeliveryMode:
1597 {
1598 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1599 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1600
1601 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1602 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
1603 DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
1604 return OMX_ErrorUnsupportedSetting;
1605 }
1606 } else {
1607 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
1608 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
1609 return OMX_ErrorBadPortIndex;
1610 }
1611
1612 break;
1613 }
1614 case OMX_ExtraDataVideoEncoderSliceInfo:
1615 {
1616 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
1617 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1618
1619 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
1620 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
1621 return false;
1622 }
1623
1624 extradata = true;
1625 break;
1626 }
1627 case OMX_ExtraDataVideoEncoderMBInfo:
1628 {
1629 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
1630 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
1631
1632 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
1633 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
1634 return false;
1635 }
1636
1637 extradata = true;
1638 break;
1639 }
1640 case OMX_QcomIndexParamSequenceHeaderWithIDR:
1641 {
1642 PrependSPSPPSToIDRFramesParams * pParam =
1643 (PrependSPSPPSToIDRFramesParams *)paramData;
1644
1645 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
1646 if(venc_set_inband_video_header(pParam->bEnable) == false) {
1647 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
1648 return OMX_ErrorUnsupportedSetting;
1649 }
1650
1651 break;
1652 }
1653 case OMX_QcomIndexParamH264AUDelimiter:
1654 {
1655 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
1656 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
1657
1658 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
1659 if(venc_set_au_delimiter(pParam->bEnable) == false) {
1660 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
1661 return OMX_ErrorUnsupportedSetting;
1662 }
1663
1664 break;
1665 }
1666 case OMX_QcomIndexHierarchicalStructure:
1667 {
1668 QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
1669 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
1670
1671 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1672 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
1673 DEBUG_PRINT_ERROR("Setting Hier P count failed");
1674 return false;
1675 }
1676 } else {
1677 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
1678 return false;
1679 }
1680
1681 // For VP8, hier-p and ltr are mutually exclusive features in firmware
1682 // Disable ltr if hier-p is enabled.
1683 if (m_codec == OMX_VIDEO_CodingVP8) {
1684 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
1685 if(!venc_set_ltrmode(0, 1)) {
1686 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
1687 }
1688 }
1689 break;
1690 }
1691 case OMX_QcomIndexParamPerfLevel:
1692 {
1693 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
1694 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
1695 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
1696 if(!venc_set_perf_level(pParam->ePerfLevel)) {
1697 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
1698 return false;
1699 } else {
1700 performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
1701 }
1702 break;
1703 }
1704 case OMX_QcomIndexParamH264VUITimingInfo:
1705 {
1706 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1707 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
1708 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
1709 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
1710 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
1711 return false;
1712 } else {
1713 vui_timing_info.enabled = (unsigned int) pParam->bEnable;
1714 }
1715 break;
1716 }
1717 case OMX_QcomIndexParamPeakBitrate:
1718 {
1719 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
1720 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
1721 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
1722 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
1723 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
1724 return false;
1725 } else {
1726 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
1727 }
1728 break;
1729 }
1730 case OMX_QcomIndexParamSetMVSearchrange:
1731 {
1732 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
1733 is_searchrange_set = true;
1734 if (!venc_set_searchrange()) {
1735 DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
1736 return false;
1737 }
1738 }
1739 break;
1740 case OMX_IndexParamVideoSliceFMO:
1741 default:
1742 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
1743 index);
1744 break;
1745 //case
1746 }
1747
1748 return true;
1749 }
1750
venc_set_config(void * configData,OMX_INDEXTYPE index)1751 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
1752 {
1753
1754 DEBUG_PRINT_LOW("Inside venc_set_config");
1755
1756 switch ((int)index) {
1757 case OMX_IndexConfigVideoBitrate:
1758 {
1759 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
1760 configData;
1761 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
1762
1763 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1764 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
1765 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
1766 return false;
1767 }
1768 } else {
1769 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
1770 }
1771
1772 break;
1773 }
1774 case OMX_IndexConfigVideoFramerate:
1775 {
1776 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
1777 configData;
1778 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
1779
1780 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1781 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
1782 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1783 return false;
1784 }
1785 } else {
1786 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1787 }
1788
1789 break;
1790 }
1791 case QOMX_IndexConfigVideoIntraperiod:
1792 {
1793 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
1794 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
1795 (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
1796
1797 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1798 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
1799 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
1800 return false;
1801 }
1802 }
1803
1804 break;
1805 }
1806 case OMX_IndexConfigVideoIntraVOPRefresh:
1807 {
1808 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
1809 configData;
1810 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
1811
1812 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1813 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
1814 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
1815 return false;
1816 }
1817 } else {
1818 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
1819 }
1820
1821 break;
1822 }
1823 case OMX_IndexConfigCommonRotate:
1824 {
1825 OMX_CONFIG_ROTATIONTYPE *config_rotation =
1826 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1827 OMX_U32 nFrameWidth;
1828 if (true == deinterlace_enabled) {
1829 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
1830 return false;
1831 }
1832 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
1833 nFrameWidth = m_sVenc_cfg.dvs_width;
1834 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height;
1835 m_sVenc_cfg.dvs_height = nFrameWidth;
1836
1837 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
1838 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
1839 return false;
1840 }
1841
1842 break;
1843 }
1844 case OMX_IndexConfigVideoAVCIntraPeriod:
1845 {
1846 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
1847 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
1848
1849 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
1850 == false) {
1851 DEBUG_PRINT_ERROR("ERROR: Setting "
1852 "OMX_IndexConfigVideoAVCIntraPeriod failed");
1853 return false;
1854 }
1855 break;
1856 }
1857 case OMX_IndexConfigCommonDeinterlace:
1858 {
1859 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
1860 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
1861 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
1862 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
1863 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
1864 {
1865 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
1866 return false;
1867 }
1868 if(venc_set_deinterlace(deinterlace->nEnable) == false) {
1869 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
1870 return false;
1871 }
1872 } else {
1873 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
1874 }
1875 break;
1876 }
1877 case OMX_IndexConfigVideoVp8ReferenceFrame:
1878 {
1879 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
1880 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
1881 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
1882 (vp8refframe->bUseGoldenFrame)) {
1883 if(venc_set_useltr() == false) {
1884 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
1885 return false;
1886 }
1887 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
1888 (vp8refframe->bGoldenFrameRefresh)) {
1889 if(venc_set_markltr() == false) {
1890 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
1891 return false;
1892 }
1893 } else {
1894 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
1895 }
1896 break;
1897 }
1898 default:
1899 DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
1900 break;
1901 }
1902
1903 return true;
1904 }
1905
venc_stop(void)1906 unsigned venc_dev::venc_stop( void)
1907 {
1908 struct venc_msg venc_msg;
1909 struct v4l2_requestbuffers bufreq;
1910 int rc = 0, ret = 0;
1911
1912 if (!stopped) {
1913 enum v4l2_buf_type cap_type;
1914
1915 if (streaming[OUTPUT_PORT]) {
1916 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1917 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1918
1919 if (rc) {
1920 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
1921 cap_type, rc);
1922 } else
1923 streaming[OUTPUT_PORT] = false;
1924
1925 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
1926 bufreq.memory = V4L2_MEMORY_USERPTR;
1927 bufreq.count = 0;
1928 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1929 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1930
1931 if (ret) {
1932 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
1933 return false;
1934 }
1935 }
1936
1937 if (!rc && streaming[CAPTURE_PORT]) {
1938 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1939 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
1940
1941 if (rc) {
1942 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
1943 cap_type, rc);
1944 } else
1945 streaming[CAPTURE_PORT] = false;
1946
1947 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
1948 bufreq.memory = V4L2_MEMORY_USERPTR;
1949 bufreq.count = 0;
1950 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1951 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
1952
1953 if (ret) {
1954 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
1955 return false;
1956 }
1957 }
1958
1959 if (!rc && !ret) {
1960 venc_stop_done();
1961 stopped = 1;
1962 /*set flag to re-configure when started again*/
1963 resume_in_stopped = 1;
1964
1965 }
1966 }
1967
1968 return rc;
1969 }
1970
venc_pause(void)1971 unsigned venc_dev::venc_pause(void)
1972 {
1973 pthread_mutex_lock(&pause_resume_mlock);
1974 paused = true;
1975 pthread_mutex_unlock(&pause_resume_mlock);
1976 return 0;
1977 }
1978
venc_resume(void)1979 unsigned venc_dev::venc_resume(void)
1980 {
1981 pthread_mutex_lock(&pause_resume_mlock);
1982 paused = false;
1983 pthread_mutex_unlock(&pause_resume_mlock);
1984
1985 return pthread_cond_signal(&pause_resume_cond);
1986 }
1987
venc_start_done(void)1988 unsigned venc_dev::venc_start_done(void)
1989 {
1990 struct venc_msg venc_msg;
1991 venc_msg.msgcode = VEN_MSG_START;
1992 venc_msg.statuscode = VEN_S_SUCCESS;
1993 venc_handle->async_message_process(venc_handle,&venc_msg);
1994 return 0;
1995 }
1996
venc_stop_done(void)1997 unsigned venc_dev::venc_stop_done(void)
1998 {
1999 struct venc_msg venc_msg;
2000 free_extradata();
2001 venc_msg.msgcode=VEN_MSG_STOP;
2002 venc_msg.statuscode=VEN_S_SUCCESS;
2003 venc_handle->async_message_process(venc_handle,&venc_msg);
2004 return 0;
2005 }
2006
venc_set_message_thread_id(pthread_t tid)2007 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2008 {
2009 async_thread_created = true;
2010 m_tid=tid;
2011 return 0;
2012 }
2013
2014
venc_start(void)2015 unsigned venc_dev::venc_start(void)
2016 {
2017 enum v4l2_buf_type buf_type;
2018 int ret, r;
2019 struct v4l2_control control;
2020
2021 memset(&control, 0, sizeof(control));
2022
2023 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
2024 __func__);
2025
2026 if (!venc_set_profile_level(0, 0)) {
2027 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
2028 __func__);
2029 } else {
2030 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
2031 __func__, codec_profile.profile, profile_level.level);
2032 }
2033
2034 venc_config_print();
2035
2036 if(resume_in_stopped){
2037 /*set buffercount when restarted*/
2038 venc_reconfig_reqbufs();
2039 resume_in_stopped = 0;
2040 }
2041
2042 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
2043 if (slice_mode.enable && multislice.mslice_size &&
2044 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
2045 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
2046 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
2047 MAX_SUPPORTED_SLICES_PER_FRAME);
2048 return 1;
2049 }
2050
2051 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2052 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2053 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
2054
2055 if (ret)
2056 return 1;
2057
2058 streaming[CAPTURE_PORT] = true;
2059
2060 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
2061 control.value = 1;
2062 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2063 if (ret) {
2064 DEBUG_PRINT_ERROR("failed to request seq header");
2065 return 1;
2066 }
2067
2068 stopped = 0;
2069 return 0;
2070 }
2071
venc_config_print()2072 void venc_dev::venc_config_print()
2073 {
2074
2075 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
2076 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
2077
2078 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
2079 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
2080 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2081
2082 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
2083 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
2084 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2085
2086 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld",
2087 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
2088
2089 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
2090 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
2091
2092 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2093 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2094
2095 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
2096 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
2097
2098 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
2099 session_qp_values.minqp, session_qp_values.maxqp);
2100
2101 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
2102 voptimecfg.voptime_resolution, multislice.mslice_mode,
2103 multislice.mslice_size);
2104
2105 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
2106 entropy.longentropysel, entropy.cabacmodel);
2107
2108 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
2109 dbkfilter.db_mode, dbkfilter.slicealpha_offset,
2110 dbkfilter.slicebeta_offset);
2111
2112 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
2113 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
2114
2115 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier-P layers: %d", hier_p_layers.numlayers);
2116
2117 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
2118
2119 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
2120
2121 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
2122 }
2123
venc_reconfig_reqbufs()2124 bool venc_dev::venc_reconfig_reqbufs()
2125 {
2126 struct v4l2_requestbuffers bufreq;
2127
2128 bufreq.memory = V4L2_MEMORY_USERPTR;
2129 bufreq.count = m_sInput_buff_property.actualcount;
2130 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2131 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2132 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
2133 return false;
2134 }
2135
2136 bufreq.memory = V4L2_MEMORY_USERPTR;
2137 bufreq.count = m_sOutput_buff_property.actualcount;
2138 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2139 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
2140 {
2141 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
2142 return false;
2143 }
2144 return true;
2145 }
2146
venc_flush(unsigned port)2147 unsigned venc_dev::venc_flush( unsigned port)
2148 {
2149 struct v4l2_encoder_cmd enc;
2150 DEBUG_PRINT_LOW("in %s", __func__);
2151
2152 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
2153 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
2154
2155 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
2156 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
2157 return -1;
2158 }
2159
2160 return 0;
2161
2162 }
2163
2164 //allocating I/P memory from pmem and register with the device
2165
2166
venc_use_buf(void * buf_addr,unsigned port,unsigned index)2167 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
2168 {
2169
2170 struct pmem *pmem_tmp;
2171 struct v4l2_buffer buf;
2172 struct v4l2_plane plane[VIDEO_MAX_PLANES];
2173 int rc = 0, extra_idx;
2174
2175 pmem_tmp = (struct pmem *)buf_addr;
2176 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
2177
2178 if (port == PORT_INDEX_IN) {
2179 buf.index = index;
2180 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2181 buf.memory = V4L2_MEMORY_USERPTR;
2182 plane[0].length = pmem_tmp->size;
2183 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2184 plane[0].reserved[0] = pmem_tmp->fd;
2185 plane[0].reserved[1] = 0;
2186 plane[0].data_offset = pmem_tmp->offset;
2187 buf.m.planes = plane;
2188 buf.length = 1;
2189
2190 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2191
2192 if (rc)
2193 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2194 } else if (port == PORT_INDEX_OUT) {
2195 extra_idx = EXTRADATA_IDX(num_planes);
2196
2197 if ((num_planes > 1) && (extra_idx)) {
2198 rc = allocate_extradata();
2199
2200 if (rc)
2201 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc);
2202 }
2203
2204 buf.index = index;
2205 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2206 buf.memory = V4L2_MEMORY_USERPTR;
2207 plane[0].length = pmem_tmp->size;
2208 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
2209 plane[0].reserved[0] = pmem_tmp->fd;
2210 plane[0].reserved[1] = 0;
2211 plane[0].data_offset = pmem_tmp->offset;
2212 buf.m.planes = plane;
2213 buf.length = num_planes;
2214
2215 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2216 plane[extra_idx].length = extradata_info.buffer_size;
2217 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2218 #ifdef USE_ION
2219 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2220 #endif
2221 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2222 plane[extra_idx].data_offset = 0;
2223 } else if (extra_idx >= VIDEO_MAX_PLANES) {
2224 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
2225 return OMX_ErrorBadParameter;
2226 }
2227
2228 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
2229
2230 if (rc)
2231 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
2232 } else {
2233 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
2234 return false;
2235 }
2236
2237 return true;
2238 }
2239
venc_free_buf(void * buf_addr,unsigned port)2240 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
2241 {
2242 struct pmem *pmem_tmp;
2243 struct venc_bufferpayload dev_buffer;
2244
2245 memset(&dev_buffer, 0, sizeof(dev_buffer));
2246 pmem_tmp = (struct pmem *)buf_addr;
2247
2248 if (port == PORT_INDEX_IN) {
2249 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2250 dev_buffer.fd = pmem_tmp->fd;
2251 dev_buffer.maped_size = pmem_tmp->size;
2252 dev_buffer.sz = pmem_tmp->size;
2253 dev_buffer.offset = pmem_tmp->offset;
2254 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2255 dev_buffer.pbuffer, \
2256 dev_buffer.fd, \
2257 dev_buffer.offset, \
2258 dev_buffer.maped_size);
2259
2260 } else if (port == PORT_INDEX_OUT) {
2261 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2262 dev_buffer.fd = pmem_tmp->fd;
2263 dev_buffer.sz = pmem_tmp->size;
2264 dev_buffer.maped_size = pmem_tmp->size;
2265 dev_buffer.offset = pmem_tmp->offset;
2266
2267 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2268 dev_buffer.pbuffer, \
2269 dev_buffer.fd, \
2270 dev_buffer.offset, \
2271 dev_buffer.maped_size);
2272 } else {
2273 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
2274 return false;
2275 }
2276
2277 return true;
2278 }
2279
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2280 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
2281 OMX_U32 width, OMX_U32 height)
2282 {
2283 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2284 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2285 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2286 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2287 src_chroma_offset = width * height;
2288
2289 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2290 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2291 //Do chroma first, so that we can convert it in-place
2292 src_buf += width * height;
2293 dst_buf += y_stride * y_scanlines;
2294 for (int line = height / 2 - 1; line >= 0; --line) {
2295 memmove(dst_buf + line * uv_stride,
2296 src_buf + line * width,
2297 width);
2298 }
2299
2300 dst_buf = src_buf = buffer->pBuffer;
2301 //Copy the Y next
2302 for (int line = height - 1; line > 0; --line) {
2303 memmove(dst_buf + line * y_stride,
2304 src_buf + line * width,
2305 width);
2306 }
2307 } else {
2308 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
2309 Insufficient bufferLen=%u v/s Required=%u",
2310 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
2311 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
2312 return false;
2313 }
2314
2315 return true;
2316 }
2317
venc_get_performance_level(OMX_U32 * perflevel)2318 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
2319 {
2320 if (!perflevel) {
2321 DEBUG_PRINT_ERROR("Null pointer error");
2322 return false;
2323 } else {
2324 *perflevel = performance_level.perflevel;
2325 return true;
2326 }
2327 }
2328
venc_get_vui_timing_info(OMX_U32 * enabled)2329 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
2330 {
2331 if (!enabled) {
2332 DEBUG_PRINT_ERROR("Null pointer error");
2333 return false;
2334 } else {
2335 *enabled = vui_timing_info.enabled;
2336 return true;
2337 }
2338 }
2339
venc_get_peak_bitrate(OMX_U32 * peakbitrate)2340 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
2341 {
2342 if (!peakbitrate) {
2343 DEBUG_PRINT_ERROR("Null pointer error");
2344 return false;
2345 } else {
2346 *peakbitrate = peak_bitrate.peakbitrate;
2347 return true;
2348 }
2349 }
2350
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2351 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
2352 {
2353 struct pmem *temp_buffer;
2354 struct v4l2_buffer buf;
2355 struct v4l2_plane plane;
2356 int rc=0;
2357 struct OMX_BUFFERHEADERTYPE *bufhdr;
2358 encoder_media_buffer_type * meta_buf = NULL;
2359 temp_buffer = (struct pmem *)buffer;
2360
2361 memset (&buf, 0, sizeof(buf));
2362 memset (&plane, 0, sizeof(plane));
2363
2364 if (buffer == NULL) {
2365 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
2366 return false;
2367 }
2368
2369 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2370
2371 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
2372
2373 if (pmem_data_buf) {
2374 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
2375 plane.m.userptr = (unsigned long)pmem_data_buf;
2376 plane.data_offset = bufhdr->nOffset;
2377 plane.length = bufhdr->nAllocLen;
2378 plane.bytesused = bufhdr->nFilledLen;
2379 } else {
2380 // --------------------------------------------------------------------------------------
2381 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info]
2382 // ---------------------------------------------------------------------------------------
2383 // Camera-2 1 CameraSource 0 meta-handle
2384 // Camera-3 1 GrallocSource 0 gralloc-private-handle
2385 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted)
2386 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr
2387 // ---------------------------------------------------------------------------------------
2388 if (metadatamode) {
2389 plane.m.userptr = index;
2390 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
2391
2392 if (!meta_buf) {
2393 //empty EOS buffer
2394 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
2395 plane.data_offset = bufhdr->nOffset;
2396 plane.length = bufhdr->nAllocLen;
2397 plane.bytesused = bufhdr->nFilledLen;
2398 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
2399 } else {
2400 return false;
2401 }
2402 } else if (!color_format) {
2403 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
2404 if (meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709)
2405 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
2406 plane.data_offset = meta_buf->meta_handle->data[1];
2407 plane.length = meta_buf->meta_handle->data[2];
2408 plane.bytesused = meta_buf->meta_handle->data[2];
2409 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
2410 fd, plane.bytesused, plane.length, buf.flags);
2411 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
2412 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
2413 fd = handle->fd;
2414 plane.data_offset = 0;
2415 plane.length = handle->size;
2416 plane.bytesused = handle->size;
2417 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
2418 ": filled %d of %d", fd, plane.bytesused, plane.length);
2419 }
2420 } else {
2421 plane.data_offset = bufhdr->nOffset;
2422 plane.length = bufhdr->nAllocLen;
2423 plane.bytesused = bufhdr->nFilledLen;
2424 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
2425 ": filled %d of %d", fd, plane.bytesused, plane.length);
2426 }
2427 } else {
2428 plane.data_offset = bufhdr->nOffset;
2429 plane.length = bufhdr->nAllocLen;
2430 plane.bytesused = bufhdr->nFilledLen;
2431 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
2432 fd, plane.bytesused, plane.length);
2433 }
2434 }
2435
2436 buf.index = index;
2437 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2438 buf.memory = V4L2_MEMORY_USERPTR;
2439 plane.reserved[0] = fd;
2440 plane.reserved[1] = 0;
2441 buf.m.planes = &plane;
2442 buf.length = 1;
2443
2444 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2445 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
2446
2447 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
2448 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
2449 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2450
2451 if (rc) {
2452 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
2453 return false;
2454 }
2455
2456 etb++;
2457
2458 if (!streaming[OUTPUT_PORT]) {
2459 enum v4l2_buf_type buf_type;
2460 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2461 int ret;
2462 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
2463
2464 if (ret) {
2465 DEBUG_PRINT_ERROR("Failed to call streamon");
2466 return false;
2467 } else {
2468 streaming[OUTPUT_PORT] = true;
2469 }
2470 }
2471 if (m_debug.in_buffer_log) {
2472 venc_input_log_buffers(bufhdr, fd, plane.data_offset);
2473 }
2474
2475 return true;
2476 }
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2477 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
2478 {
2479 struct pmem *temp_buffer = NULL;
2480 struct venc_buffer frameinfo;
2481 struct v4l2_buffer buf;
2482 struct v4l2_plane plane[VIDEO_MAX_PLANES];
2483 int rc = 0, extra_idx;
2484 struct OMX_BUFFERHEADERTYPE *bufhdr;
2485
2486 if (buffer == NULL)
2487 return false;
2488
2489 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2490
2491 if (pmem_data_buf) {
2492 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
2493 plane[0].m.userptr = (unsigned long)pmem_data_buf;
2494 } else {
2495 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
2496 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
2497 }
2498
2499 buf.index = index;
2500 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2501 buf.memory = V4L2_MEMORY_USERPTR;
2502 plane[0].length = bufhdr->nAllocLen;
2503 plane[0].bytesused = bufhdr->nFilledLen;
2504 plane[0].reserved[0] = fd;
2505 plane[0].reserved[1] = 0;
2506 plane[0].data_offset = bufhdr->nOffset;
2507 buf.m.planes = plane;
2508 buf.length = num_planes;
2509
2510 extra_idx = EXTRADATA_IDX(num_planes);
2511
2512 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2513 plane[extra_idx].bytesused = 0;
2514 plane[extra_idx].length = extradata_info.buffer_size;
2515 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
2516 #ifdef USE_ION
2517 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
2518 #endif
2519 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
2520 plane[extra_idx].data_offset = 0;
2521 } else if (extra_idx >= VIDEO_MAX_PLANES) {
2522 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
2523 return false;
2524 }
2525
2526 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
2527
2528 if (rc) {
2529 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
2530 return false;
2531 }
2532
2533 ftb++;
2534 return true;
2535 }
2536
venc_set_inband_video_header(OMX_BOOL enable)2537 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
2538 {
2539 struct v4l2_control control;
2540
2541 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
2542 if(enable) {
2543 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
2544 } else {
2545 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
2546 }
2547
2548 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
2549 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2550 DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
2551 return false;
2552 }
2553 return true;
2554 }
2555
venc_set_au_delimiter(OMX_BOOL enable)2556 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
2557 {
2558 struct v4l2_control control;
2559
2560 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
2561 if(enable) {
2562 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
2563 } else {
2564 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
2565 }
2566
2567 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
2568 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
2569 DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
2570 return false;
2571 }
2572 return true;
2573 }
2574
venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,OMX_U32 num_layers)2575 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
2576 OMX_U32 num_layers)
2577 {
2578 struct v4l2_control control;
2579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
2580 if (type == QOMX_HIERARCHICALCODING_P) {
2581 control.value = num_layers;
2582 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
2583 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2584 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
2585 return false;
2586 }
2587 hier_p_layers.numlayers = num_layers;
2588 } else {
2589 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
2590 return false;
2591 }
2592 return true;
2593 }
2594
venc_set_extradata(OMX_U32 extra_data,OMX_BOOL enable)2595 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
2596 {
2597 struct v4l2_control control;
2598
2599 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
2600
2601 if (enable == OMX_FALSE) {
2602 /* No easy way to turn off extradata to the driver
2603 * at the moment */
2604 return false;
2605 }
2606
2607 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2608 switch (extra_data) {
2609 case OMX_ExtraDataVideoEncoderSliceInfo:
2610 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
2611 break;
2612 case OMX_ExtraDataVideoEncoderMBInfo:
2613 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
2614 break;
2615 default:
2616 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
2617 return false;
2618 }
2619
2620 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2621 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
2622 (unsigned int)extra_data, errno);
2623 return false;
2624 }
2625
2626 return true;
2627 }
2628
venc_set_slice_delivery_mode(OMX_U32 enable)2629 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
2630 {
2631 struct v4l2_control control;
2632
2633 if (enable) {
2634 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
2635 control.value = 1;
2636 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
2637
2638 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2639 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2640 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
2641 return false;
2642 } else {
2643 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
2644 slice_mode.enable = 1;
2645 }
2646 } else {
2647 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
2648 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
2649 m_sVenc_cfg.codectype);
2650 }
2651 } else {
2652 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
2653 }
2654
2655 return true;
2656 }
2657
venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp)2658 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
2659 {
2660 int rc;
2661 struct v4l2_control control;
2662 struct v4l2_ext_control ctrl[4];
2663 struct v4l2_ext_controls controls;
2664
2665 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
2666 ctrl[0].value = initqp->nQpI;
2667 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
2668 ctrl[1].value = initqp->nQpP;
2669 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
2670 ctrl[2].value = initqp->nQpB;
2671 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
2672 ctrl[3].value = initqp->bEnableInitQp;
2673
2674 controls.count = 4;
2675 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
2676 controls.controls = ctrl;
2677
2678 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
2679 controls.controls[0].id, controls.controls[0].value,
2680 controls.controls[1].id, controls.controls[1].value,
2681 controls.controls[2].id, controls.controls[2].value,
2682 controls.controls[3].id, controls.controls[3].value);
2683
2684 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
2685 if (rc) {
2686 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
2687 return false;
2688 }
2689
2690 init_qp.iframeqp = initqp->nQpI;
2691 init_qp.pframeqp = initqp->nQpP;
2692 init_qp.bframeqp = initqp->nQpB;
2693 init_qp.enableinitqp = initqp->bEnableInitQp;
2694
2695 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
2696 controls.controls[0].id, controls.controls[0].value,
2697 controls.controls[1].id, controls.controls[1].value,
2698 controls.controls[2].id, controls.controls[2].value,
2699 controls.controls[3].id, controls.controls[3].value);
2700 return true;
2701 }
2702
venc_set_session_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)2703 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
2704 {
2705 int rc;
2706 struct v4l2_control control;
2707
2708 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
2709 control.value = i_frame_qp;
2710
2711 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2712 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2713
2714 if (rc) {
2715 DEBUG_PRINT_ERROR("Failed to set control");
2716 return false;
2717 }
2718
2719 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2720 session_qp.iframeqp = control.value;
2721
2722 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
2723 control.value = p_frame_qp;
2724
2725 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2726 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2727
2728 if (rc) {
2729 DEBUG_PRINT_ERROR("Failed to set control");
2730 return false;
2731 }
2732
2733 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2734
2735 session_qp.pframeqp = control.value;
2736
2737 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
2738 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
2739
2740 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
2741 control.value = b_frame_qp;
2742
2743 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
2744 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2745
2746 if (rc) {
2747 DEBUG_PRINT_ERROR("Failed to set control");
2748 return false;
2749 }
2750
2751 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
2752
2753 session_qp.bframeqp = control.value;
2754 }
2755
2756 return true;
2757 }
2758
venc_set_session_qp_range(OMX_U32 min_qp,OMX_U32 max_qp)2759 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
2760 {
2761 int rc;
2762 struct v4l2_control control;
2763
2764 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
2765
2766 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
2767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
2768 else
2769 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
2770 control.value = min_qp;
2771
2772 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
2773 control.id, control.value);
2774 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2775 if (rc) {
2776 DEBUG_PRINT_ERROR("Failed to set control\n");
2777 return false;
2778 }
2779
2780 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
2781 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
2782 else
2783 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
2784 control.value = max_qp;
2785
2786 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
2787 control.id, control.value);
2788 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
2789 if (rc) {
2790 DEBUG_PRINT_ERROR("Failed to set control\n");
2791 return false;
2792 }
2793 } else {
2794 DEBUG_PRINT_ERROR("Wrong qp values[%lu %lu], allowed range[%lu %lu]",
2795 min_qp, max_qp, session_qp_range.minqp, session_qp_range.maxqp);
2796 }
2797
2798 return true;
2799 }
2800
venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)2801 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
2802 {
2803 struct venc_profile requested_profile = {0};
2804 struct ven_profilelevel requested_level = {0};
2805 unsigned long mb_per_frame = 0;
2806 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
2807 (unsigned int)eProfile, (unsigned int)eLevel);
2808 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
2809 ((m_sVenc_cfg.dvs_width + 15) >> 4);
2810
2811 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
2812 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
2813 return true;
2814 }
2815
2816 DEBUG_PRINT_LOW("Validating Profile/Level from table");
2817
2818 if (!venc_validate_profile_level(&eProfile, &eLevel)) {
2819 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
2820 return false;
2821 }
2822
2823 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
2824 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
2825 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
2826 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
2827
2828 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
2829 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
2830 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
2831 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
2832 } else {
2833 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
2834 (unsigned int)eProfile);
2835 return false;
2836 }
2837
2838 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
2839 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
2840 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
2841 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
2842
2843 if (mb_per_frame >= 3600) {
2844 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
2845 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2846
2847 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
2848 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2849 } else {
2850 switch (eLevel) {
2851 case OMX_VIDEO_MPEG4Level0:
2852 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
2853 break;
2854 case OMX_VIDEO_MPEG4Level0b:
2855 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
2856 break;
2857 case OMX_VIDEO_MPEG4Level1:
2858 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
2859 break;
2860 case OMX_VIDEO_MPEG4Level2:
2861 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
2862 break;
2863 case OMX_VIDEO_MPEG4Level3:
2864 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
2865 break;
2866 case OMX_VIDEO_MPEG4Level4a:
2867 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
2868 break;
2869 case OMX_VIDEO_MPEG4Level5:
2870 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
2871 break;
2872 default:
2873 return false;
2874 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
2875 break;
2876 }
2877 }
2878 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
2879
2880 switch (eProfile) {
2881 case OMX_VIDEO_H263ProfileBaseline:
2882 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
2883 break;
2884 case OMX_VIDEO_H263ProfileH320Coding:
2885 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
2886 break;
2887 case OMX_VIDEO_H263ProfileBackwardCompatible:
2888 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
2889 break;
2890 case OMX_VIDEO_H263ProfileISWV2:
2891 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
2892 break;
2893 case OMX_VIDEO_H263ProfileISWV3:
2894 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
2895 break;
2896 case OMX_VIDEO_H263ProfileHighCompression:
2897 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
2898 break;
2899 case OMX_VIDEO_H263ProfileInternet:
2900 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
2901 break;
2902 case OMX_VIDEO_H263ProfileInterlace:
2903 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
2904 break;
2905 case OMX_VIDEO_H263ProfileHighLatency:
2906 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
2907 break;
2908 default:
2909 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
2910 requested_profile.profile);
2911 return false;
2912 }
2913
2914 //profile level
2915 switch (eLevel) {
2916 case OMX_VIDEO_H263Level10:
2917 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
2918 break;
2919 case OMX_VIDEO_H263Level20:
2920 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
2921 break;
2922 case OMX_VIDEO_H263Level30:
2923 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
2924 break;
2925 case OMX_VIDEO_H263Level40:
2926 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
2927 break;
2928 case OMX_VIDEO_H263Level45:
2929 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
2930 break;
2931 case OMX_VIDEO_H263Level50:
2932 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
2933 break;
2934 case OMX_VIDEO_H263Level60:
2935 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
2936 break;
2937 case OMX_VIDEO_H263Level70:
2938 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
2939 break;
2940 default:
2941 return false;
2942 break;
2943 }
2944 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
2945 if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
2946 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
2947 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
2948 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
2949 } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
2950 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
2951 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
2952 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
2953 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
2954 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
2955 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
2956 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
2957 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
2958 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
2959 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
2960 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
2961 } else {
2962 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
2963 requested_profile.profile);
2964 return false;
2965 }
2966
2967 //profile level
2968 switch (eLevel) {
2969 case OMX_VIDEO_AVCLevel1:
2970 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
2971 break;
2972 case OMX_VIDEO_AVCLevel1b:
2973 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
2974 break;
2975 case OMX_VIDEO_AVCLevel11:
2976 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
2977 break;
2978 case OMX_VIDEO_AVCLevel12:
2979 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
2980 break;
2981 case OMX_VIDEO_AVCLevel13:
2982 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
2983 break;
2984 case OMX_VIDEO_AVCLevel2:
2985 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
2986 break;
2987 case OMX_VIDEO_AVCLevel21:
2988 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
2989 break;
2990 case OMX_VIDEO_AVCLevel22:
2991 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
2992 break;
2993 case OMX_VIDEO_AVCLevel3:
2994 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
2995 break;
2996 case OMX_VIDEO_AVCLevel31:
2997 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
2998 break;
2999 case OMX_VIDEO_AVCLevel32:
3000 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
3001 break;
3002 case OMX_VIDEO_AVCLevel4:
3003 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
3004 break;
3005 case OMX_VIDEO_AVCLevel41:
3006 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
3007 break;
3008 case OMX_VIDEO_AVCLevel42:
3009 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
3010 break;
3011 case OMX_VIDEO_AVCLevel5:
3012 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
3013 break;
3014 case OMX_VIDEO_AVCLevel51:
3015 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
3016 break;
3017 case OMX_VIDEO_AVCLevel52:
3018 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3019 break;
3020 case OMX_VIDEO_AVCLevelMax:
3021 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
3022 break;
3023 default :
3024 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
3025 requested_level.level);
3026 return false;
3027 break;
3028 }
3029 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3030 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
3031 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
3032 (unsigned int)eProfile);
3033 return false;
3034 }
3035 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
3036 m_profile_set = true;
3037 switch(eLevel) {
3038 case OMX_VIDEO_VP8Level_Version0:
3039 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
3040 break;
3041 case OMX_VIDEO_VP8Level_Version1:
3042 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
3043 break;
3044 default:
3045 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
3046 (unsigned int)eLevel);
3047 return false;
3048 break;
3049 }
3050 }
3051
3052 if (!m_profile_set) {
3053 int rc;
3054 struct v4l2_control control;
3055
3056 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3057 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3058 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3059 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
3060 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3061 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
3062 } else {
3063 DEBUG_PRINT_ERROR("Wrong CODEC");
3064 return false;
3065 }
3066
3067 control.value = requested_profile.profile;
3068
3069 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3070 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3071
3072 if (rc) {
3073 DEBUG_PRINT_ERROR("Failed to set control");
3074 return false;
3075 }
3076
3077 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3078
3079 codec_profile.profile = control.value;
3080 m_profile_set = true;
3081 }
3082
3083 if (!m_level_set) {
3084 int rc;
3085 struct v4l2_control control;
3086
3087 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3088 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3089 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3090 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
3091 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3092 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
3093 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
3094 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3095 } else {
3096 DEBUG_PRINT_ERROR("Wrong CODEC");
3097 return false;
3098 }
3099
3100 control.value = requested_level.level;
3101
3102 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3103 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3104
3105 if (rc) {
3106 DEBUG_PRINT_ERROR("Failed to set control");
3107 return false;
3108 }
3109
3110 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3111
3112 profile_level.level = control.value;
3113 m_level_set = true;
3114 }
3115
3116 return true;
3117 }
3118
venc_set_voptiming_cfg(OMX_U32 TimeIncRes)3119 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
3120 {
3121
3122 struct venc_voptimingcfg vop_timing_cfg;
3123
3124 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
3125 (unsigned int)TimeIncRes);
3126
3127 vop_timing_cfg.voptime_resolution = TimeIncRes;
3128
3129 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
3130 return true;
3131 }
3132
venc_set_intra_period(OMX_U32 nPFrames,OMX_U32 nBFrames)3133 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
3134 {
3135
3136 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
3137 int rc;
3138 struct v4l2_control control;
3139 int pframe = 0, bframe = 0;
3140
3141 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
3142 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
3143 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
3144 nBFrames=0;
3145 }
3146 if ((display_info.w * display_info.h > OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
3147 && enable_mv_narrow_searchrange && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >=
3148 OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT || is_searchrange_set)) {
3149 nBFrames=0;
3150 }
3151
3152 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
3153 control.value = nPFrames;
3154 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3155
3156 if (rc) {
3157 DEBUG_PRINT_ERROR("Failed to set control");
3158 return false;
3159 }
3160
3161 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3162
3163 intra_period.num_pframes = control.value;
3164 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
3165 control.value = nBFrames;
3166 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3167 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3168
3169 if (rc) {
3170 DEBUG_PRINT_ERROR("Failed to set control");
3171 return false;
3172 }
3173
3174 intra_period.num_bframes = nBFrames;
3175 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
3176
3177 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
3178 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3179 control.value = 1;
3180
3181 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3182
3183 if (rc) {
3184 DEBUG_PRINT_ERROR("Failed to set control");
3185 return false;
3186 }
3187
3188 idrperiod.idrperiod = 1;
3189 }
3190
3191 return true;
3192 }
3193
venc_set_idr_period(OMX_U32 nPFrames,OMX_U32 nIDRPeriod)3194 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
3195 {
3196 int rc = 0;
3197 struct v4l2_control control;
3198 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
3199 (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
3200
3201 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
3202 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
3203 return false;
3204 }
3205
3206 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
3207 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
3208 return false;
3209 }
3210
3211 if (!intra_period.num_bframes)
3212 intra_period.num_pframes = nPFrames;
3213 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
3214 control.value = nIDRPeriod;
3215
3216 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3217
3218 if (rc) {
3219 DEBUG_PRINT_ERROR("Failed to set control");
3220 return false;
3221 }
3222
3223 idrperiod.idrperiod = nIDRPeriod;
3224 return true;
3225 }
3226
venc_set_entropy_config(OMX_BOOL enable,OMX_U32 i_cabac_level)3227 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
3228 {
3229 int rc = 0;
3230 struct v4l2_control control;
3231
3232 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
3233
3234 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
3235 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
3236
3237 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
3238 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3239
3240 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3241 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3242
3243 if (rc) {
3244 DEBUG_PRINT_ERROR("Failed to set control");
3245 return false;
3246 }
3247
3248 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3249 entropy.longentropysel = control.value;
3250
3251 if (i_cabac_level == 0) {
3252 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
3253 } else if (i_cabac_level == 1) {
3254 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
3255 } else if (i_cabac_level == 2) {
3256 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
3257 }
3258
3259 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
3260 //control.value = entropy_cfg.cabacmodel;
3261 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3262 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3263
3264 if (rc) {
3265 DEBUG_PRINT_ERROR("Failed to set control");
3266 return false;
3267 }
3268
3269 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3270 entropy.cabacmodel=control.value;
3271 } else if (!enable) {
3272 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
3273 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
3274 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3275 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3276
3277 if (rc) {
3278 DEBUG_PRINT_ERROR("Failed to set control");
3279 return false;
3280 }
3281
3282 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3283 entropy.longentropysel=control.value;
3284 } else {
3285 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
3286 return false;
3287 }
3288
3289 return true;
3290 }
3291
venc_set_multislice_cfg(OMX_INDEXTYPE Codec,OMX_U32 nSlicesize)3292 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
3293 {
3294 int rc;
3295 struct v4l2_control control;
3296 bool status = true;
3297
3298 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) {
3299 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
3300 } else {
3301 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3302 }
3303
3304 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3305 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3306 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3307
3308 if (rc) {
3309 DEBUG_PRINT_ERROR("Failed to set control");
3310 return false;
3311 }
3312
3313 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3314 multislice.mslice_mode=control.value;
3315
3316 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
3317
3318 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
3319 control.value = nSlicesize;
3320 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
3321 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3322
3323 if (rc) {
3324 DEBUG_PRINT_ERROR("Failed to set control");
3325 return false;
3326 }
3327
3328 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3329 multislice.mslice_size=control.value;
3330
3331 }
3332
3333 return status;
3334 }
3335
venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode,OMX_U32 irMBs)3336 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
3337 {
3338 bool status = true;
3339 int rc;
3340 struct v4l2_control control_mode,control_mbs;
3341 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
3342
3343 // There is no disabled mode. Disabled mode is indicated by a 0 count.
3344 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
3345 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
3346 return status;
3347 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
3348 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3349 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
3350 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
3351 control_mbs.value=irMBs;
3352 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
3353 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3354 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
3355 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
3356 control_mbs.value=irMBs;
3357 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
3358 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
3359 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
3360 } else {
3361 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
3362 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
3363 return false;
3364 }
3365
3366 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
3367 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
3368
3369 if (rc) {
3370 DEBUG_PRINT_ERROR("Failed to set control");
3371 return false;
3372 }
3373
3374 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
3375
3376 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
3377 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
3378
3379 if (rc) {
3380 DEBUG_PRINT_ERROR("Failed to set control");
3381 return false;
3382 }
3383
3384 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
3385
3386 intra_refresh.irmode = control_mode.value;
3387 intra_refresh.mbcount = control_mbs.value;
3388
3389 return status;
3390 }
3391
venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE * error_resilience)3392 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
3393 {
3394 bool status = true;
3395 struct venc_headerextension hec_cfg;
3396 struct venc_multiclicecfg multislice_cfg;
3397 int rc;
3398 OMX_U32 resynchMarkerSpacingBytes = 0;
3399 struct v4l2_control control;
3400
3401 memset(&control, 0, sizeof(control));
3402
3403 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3404 if (error_resilience->bEnableHEC) {
3405 hec_cfg.header_extension = 1;
3406 } else {
3407 hec_cfg.header_extension = 0;
3408 }
3409
3410 hec.header_extension = error_resilience->bEnableHEC;
3411 }
3412
3413 if (error_resilience->bEnableRVLC) {
3414 DEBUG_PRINT_ERROR("RVLC is not Supported");
3415 return false;
3416 }
3417
3418 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3419 (error_resilience->bEnableDataPartitioning)) {
3420 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
3421 return false;
3422 }
3423
3424 if (error_resilience->nResynchMarkerSpacing) {
3425 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
3426 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
3427 }
3428 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
3429 (error_resilience->nResynchMarkerSpacing)) {
3430 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
3431 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3432 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3433 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
3434 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
3435 error_resilience->bEnableDataPartitioning) {
3436 multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
3437 multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
3438 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3439 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
3440 } else {
3441 multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
3442 multislice_cfg.mslice_size = 0;
3443 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
3444 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
3445 }
3446
3447 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
3448 multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
3449 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3450 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3451
3452 if (rc) {
3453 DEBUG_PRINT_ERROR("Failed to set Slice mode control");
3454 return false;
3455 }
3456
3457 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3458 multislice.mslice_mode=control.value;
3459
3460 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
3461 control.value = resynchMarkerSpacingBytes;
3462 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3463
3464 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3465
3466 if (rc) {
3467 DEBUG_PRINT_ERROR("Failed to set MAX MB control");
3468 return false;
3469 }
3470
3471 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3472 multislice.mslice_mode = multislice_cfg.mslice_mode;
3473 multislice.mslice_size = multislice_cfg.mslice_size;
3474 return status;
3475 }
3476
venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)3477 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
3478 {
3479 int rc;
3480 struct v4l2_control control;
3481 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
3482
3483 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
3484 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
3485 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
3486 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
3487 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
3488 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
3489 }
3490
3491 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3492 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3493
3494 if (rc) {
3495 return false;
3496 }
3497
3498 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3499
3500 dbkfilter.db_mode=control.value;
3501
3502 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
3503 control.value=0;
3504
3505 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3506 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3507
3508 if (rc) {
3509 return false;
3510 }
3511
3512 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3513 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
3514 control.value=0;
3515 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3516 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3517
3518 if (rc) {
3519 return false;
3520 }
3521
3522 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3523
3524
3525 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
3526 return true;
3527 }
3528
venc_set_target_bitrate(OMX_U32 nTargetBitrate,OMX_U32 config)3529 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
3530 {
3531 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
3532 (unsigned int)nTargetBitrate);
3533 struct v4l2_control control;
3534 int rc = 0;
3535 control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
3536 control.value = nTargetBitrate;
3537
3538 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3539 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3540
3541 if (rc) {
3542 DEBUG_PRINT_ERROR("Failed to set control");
3543 return false;
3544 }
3545
3546 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3547
3548
3549 m_sVenc_cfg.targetbitrate = control.value;
3550 bitrate.target_bitrate = control.value;
3551
3552 if (!config) {
3553 m_level_set = false;
3554
3555 if (venc_set_profile_level(0, 0)) {
3556 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
3557 }
3558 }
3559
3560 return true;
3561 }
3562
venc_set_encode_framerate(OMX_U32 encode_framerate,OMX_U32 config)3563 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
3564 {
3565 struct v4l2_streamparm parm;
3566 int rc = 0;
3567 struct venc_framerate frame_rate_cfg;
3568 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
3569 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3570 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
3571 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
3572
3573 if (frame_rate_cfg.fps_numerator > 0)
3574 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
3575
3576 if (rc) {
3577 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
3578 return false;
3579 }
3580
3581 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
3582 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
3583
3584 if (!config) {
3585 m_level_set = false;
3586
3587 if (venc_set_profile_level(0, 0)) {
3588 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
3589 }
3590 }
3591
3592 return true;
3593 }
3594
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)3595 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
3596 {
3597 struct v4l2_format fmt;
3598 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
3599
3600 if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar ||
3601 (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
3602 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3603 } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) {
3604 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
3605 } else {
3606 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
3607 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3608 DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
3609 }
3610
3611 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3612 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3613 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3614 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3615
3616 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3617 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
3618 return false;
3619 }
3620
3621 return true;
3622 }
3623
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)3624 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
3625 {
3626 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
3627
3628 if (intra_vop_refresh == OMX_TRUE) {
3629 struct v4l2_control control;
3630 int rc;
3631 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
3632 control.value = 1;
3633 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3634 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3635
3636 if (rc) {
3637 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
3638 return false;
3639 }
3640
3641 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3642 } else {
3643 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
3644 }
3645
3646 return true;
3647 }
3648
venc_set_deinterlace(OMX_U32 enable)3649 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
3650 {
3651 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
3652 struct v4l2_control control;
3653 int rc;
3654 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
3655 if (enable)
3656 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
3657 else
3658 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
3659
3660 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3661 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3662 if (rc) {
3663 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
3664 return false;
3665 }
3666 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3667 deinterlace_enabled = true;
3668 return true;
3669 }
3670
venc_set_ltrmode(OMX_U32 enable,OMX_U32 count)3671 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
3672 {
3673 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
3674 struct v4l2_control control;
3675 struct v4l2_ext_control ctrl[2];
3676 struct v4l2_ext_controls controls;
3677 int rc;
3678
3679 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
3680 if (enable)
3681 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
3682 else
3683 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
3684
3685 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
3686 if (count)
3687 ctrl[1].value = count;
3688 else
3689 ctrl[1].value = 1;
3690
3691 controls.count = 2;
3692 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3693 controls.controls = ctrl;
3694
3695 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
3696 controls.controls[0].id, controls.controls[0].value,
3697 controls.controls[1].id, controls.controls[1].value);
3698
3699 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3700 if (rc) {
3701 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
3702 return false;
3703 }
3704
3705 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
3706 controls.controls[0].id, controls.controls[0].value,
3707 controls.controls[1].id, controls.controls[1].value);
3708
3709 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
3710 control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR;
3711
3712 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3713 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
3714 return false;
3715 }
3716 return true;
3717 }
3718
venc_set_useltr()3719 bool venc_dev::venc_set_useltr()
3720 {
3721 DEBUG_PRINT_LOW("venc_use_goldenframe");
3722 int rc = true;
3723 struct v4l2_control control;
3724
3725 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
3726 control.value = 1;
3727
3728 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3729 if (rc) {
3730 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
3731 return false;
3732 }
3733
3734 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3735 control.id, control.value);
3736 return true;
3737 }
3738
venc_set_markltr()3739 bool venc_dev::venc_set_markltr()
3740 {
3741 DEBUG_PRINT_LOW("venc_set_goldenframe");
3742 int rc = true;
3743 struct v4l2_control control;
3744
3745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
3746 control.value = 1;
3747
3748 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3749 if (rc) {
3750 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
3751 return false;
3752 }
3753
3754 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3755 control.id, control.value);
3756 return true;
3757 }
3758
venc_set_vpe_rotation(OMX_S32 rotation_angle)3759 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
3760 {
3761 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
3762 struct v4l2_control control;
3763 int rc;
3764 struct v4l2_format fmt;
3765 struct v4l2_requestbuffers bufreq;
3766
3767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
3768 if (rotation_angle == 0)
3769 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
3770 else if (rotation_angle == 90)
3771 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
3772 else if (rotation_angle == 180)
3773 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
3774 else if (rotation_angle == 270)
3775 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
3776 else {
3777 DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
3778 return false;
3779 }
3780
3781 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3782 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3783 if (rc) {
3784 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
3785 return false;
3786 }
3787 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3788
3789 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3790 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
3791 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
3792 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
3793 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3794 DEBUG_PRINT_ERROR("Failed to set format on capture port");
3795 return false;
3796 }
3797
3798 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
3799 bufreq.memory = V4L2_MEMORY_USERPTR;
3800 bufreq.count = m_sOutput_buff_property.actualcount;
3801 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3802 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
3803 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
3804 return false;
3805 }
3806 if (bufreq.count >= m_sOutput_buff_property.mincount)
3807 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
3808
3809 return true;
3810 }
3811
venc_set_searchrange()3812 bool venc_dev::venc_set_searchrange()
3813 {
3814 DEBUG_PRINT_LOW("venc_set_searchrange");
3815 struct v4l2_control control;
3816 struct v4l2_ext_control ctrl[6];
3817 struct v4l2_ext_controls controls;
3818 int rc;
3819
3820 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
3821 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3822 ctrl[0].value = 16;
3823 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3824 ctrl[1].value = 4;
3825 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3826 ctrl[2].value = 16;
3827 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3828 ctrl[3].value = 4;
3829 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3830 ctrl[4].value = 12;
3831 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3832 ctrl[5].value = 4;
3833 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
3834 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
3835 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3836 ctrl[0].value = 16;
3837 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3838 ctrl[1].value = 4;
3839 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3840 ctrl[2].value = 16;
3841 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3842 ctrl[3].value = 4;
3843 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3844 ctrl[4].value = 12;
3845 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3846 ctrl[5].value = 4;
3847 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
3848 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
3849 ctrl[0].value = 4;
3850 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
3851 ctrl[1].value = 4;
3852 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
3853 ctrl[2].value = 4;
3854 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
3855 ctrl[3].value = 4;
3856 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
3857 ctrl[4].value = 4;
3858 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
3859 ctrl[5].value = 4;
3860 } else {
3861 DEBUG_PRINT_ERROR("Invalid codec type");
3862 return false;
3863 }
3864 controls.count = 6;
3865 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
3866 controls.controls = ctrl;
3867
3868 DEBUG_PRINT_LOW(" Calling IOCTL set control for"
3869 "id=%x, val=%d id=%x, val=%d"
3870 "id=%x, val=%d id=%x, val=%d"
3871 "id=%x, val=%d id=%x, val=%d",
3872 controls.controls[0].id, controls.controls[0].value,
3873 controls.controls[1].id, controls.controls[1].value,
3874 controls.controls[2].id, controls.controls[2].value,
3875 controls.controls[3].id, controls.controls[3].value,
3876 controls.controls[4].id, controls.controls[4].value,
3877 controls.controls[5].id, controls.controls[5].value);
3878
3879 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
3880 if (rc) {
3881 DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
3882 return false;
3883 }
3884 return true;
3885 }
3886
venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)3887 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
3888 {
3889 bool status = true;
3890 struct v4l2_control control;
3891 int rc = 0;
3892 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
3893
3894 switch (eControlRate) {
3895 case OMX_Video_ControlRateDisable:
3896 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
3897 break;
3898 case OMX_Video_ControlRateVariableSkipFrames:
3899 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
3900 break;
3901 case OMX_Video_ControlRateVariable:
3902 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
3903 break;
3904 case OMX_Video_ControlRateConstantSkipFrames:
3905 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
3906 break;
3907 case OMX_Video_ControlRateConstant:
3908 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
3909 break;
3910 default:
3911 status = false;
3912 break;
3913 }
3914
3915 if (status) {
3916
3917 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3918 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3919
3920 if (rc) {
3921 DEBUG_PRINT_ERROR("Failed to set control");
3922 return false;
3923 }
3924
3925 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3926
3927 rate_ctrl.rcmode = control.value;
3928 }
3929
3930 return status;
3931 }
3932
venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)3933 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
3934 {
3935 bool status = true;
3936 struct v4l2_control control;
3937 int rc = 0;
3938 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
3939
3940 switch (ePerfLevel) {
3941 case OMX_QCOM_PerfLevelNominal:
3942 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
3943 break;
3944 case OMX_QCOM_PerfLevelTurbo:
3945 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
3946 break;
3947 default:
3948 status = false;
3949 break;
3950 }
3951
3952 if (status) {
3953 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3954 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3955
3956 if (rc) {
3957 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
3958 return false;
3959 }
3960
3961 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3962 }
3963 return status;
3964 }
3965
venc_set_vui_timing_info(OMX_BOOL enable)3966 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
3967 {
3968 struct v4l2_control control;
3969 int rc = 0;
3970 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
3971
3972 if (enable)
3973 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
3974 else
3975 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
3976
3977 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3978 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3979 if (rc) {
3980 DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
3981 return false;
3982 }
3983 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3984 return true;
3985 }
3986
venc_set_peak_bitrate(OMX_U32 nPeakBitrate)3987 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
3988 {
3989 struct v4l2_control control;
3990 int rc = 0;
3991 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
3992 control.value = nPeakBitrate;
3993
3994 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
3995
3996 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3997 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3998
3999 if (rc) {
4000 DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
4001 return false;
4002 }
4003
4004 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
4005
4006 return true;
4007 }
4008
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)4009 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
4010 {
4011 bool status = true;
4012
4013 if (eProfile == NULL || eLevel == NULL) {
4014 return false;
4015 }
4016
4017 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4018 switch (codec_profile.profile) {
4019 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4020 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4021 break;
4022 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4023 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4024 break;
4025 default:
4026 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
4027 status = false;
4028 break;
4029 }
4030
4031 if (!status) {
4032 return status;
4033 }
4034
4035 //profile level
4036 switch (profile_level.level) {
4037 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
4038 *eLevel = OMX_VIDEO_MPEG4Level0;
4039 break;
4040 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
4041 *eLevel = OMX_VIDEO_MPEG4Level0b;
4042 break;
4043 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
4044 *eLevel = OMX_VIDEO_MPEG4Level1;
4045 break;
4046 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
4047 *eLevel = OMX_VIDEO_MPEG4Level2;
4048 break;
4049 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
4050 *eLevel = OMX_VIDEO_MPEG4Level3;
4051 break;
4052 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
4053 *eLevel = OMX_VIDEO_MPEG4Level4;
4054 break;
4055 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
4056 *eLevel = OMX_VIDEO_MPEG4Level5;
4057 break;
4058 default:
4059 *eLevel = OMX_VIDEO_MPEG4LevelMax;
4060 status = false;
4061 break;
4062 }
4063 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4064 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
4065 *eProfile = OMX_VIDEO_H263ProfileBaseline;
4066 } else {
4067 *eProfile = OMX_VIDEO_H263ProfileMax;
4068 return false;
4069 }
4070
4071 switch (profile_level.level) {
4072 case VEN_LEVEL_H263_10:
4073 *eLevel = OMX_VIDEO_H263Level10;
4074 break;
4075 case VEN_LEVEL_H263_20:
4076 *eLevel = OMX_VIDEO_H263Level20;
4077 break;
4078 case VEN_LEVEL_H263_30:
4079 *eLevel = OMX_VIDEO_H263Level30;
4080 break;
4081 case VEN_LEVEL_H263_40:
4082 *eLevel = OMX_VIDEO_H263Level40;
4083 break;
4084 case VEN_LEVEL_H263_45:
4085 *eLevel = OMX_VIDEO_H263Level45;
4086 break;
4087 case VEN_LEVEL_H263_50:
4088 *eLevel = OMX_VIDEO_H263Level50;
4089 break;
4090 case VEN_LEVEL_H263_60:
4091 *eLevel = OMX_VIDEO_H263Level60;
4092 break;
4093 case VEN_LEVEL_H263_70:
4094 *eLevel = OMX_VIDEO_H263Level70;
4095 break;
4096 default:
4097 *eLevel = OMX_VIDEO_H263LevelMax;
4098 status = false;
4099 break;
4100 }
4101 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4102 switch (codec_profile.profile) {
4103 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
4104 *eProfile = OMX_VIDEO_AVCProfileBaseline;
4105 break;
4106 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
4107 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
4108 break;
4109 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4110 *eProfile = OMX_VIDEO_AVCProfileMain;
4111 break;
4112 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4113 *eProfile = OMX_VIDEO_AVCProfileHigh;
4114 break;
4115 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4116 *eProfile = OMX_VIDEO_AVCProfileExtended;
4117 break;
4118 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4119 *eProfile = OMX_VIDEO_AVCProfileHigh10;
4120 break;
4121 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4122 *eProfile = OMX_VIDEO_AVCProfileHigh422;
4123 break;
4124 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4125 *eProfile = OMX_VIDEO_AVCProfileHigh444;
4126 break;
4127 default:
4128 *eProfile = OMX_VIDEO_AVCProfileMax;
4129 status = false;
4130 break;
4131 }
4132
4133 if (!status) {
4134 return status;
4135 }
4136
4137 switch (profile_level.level) {
4138 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
4139 *eLevel = OMX_VIDEO_AVCLevel1;
4140 break;
4141 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
4142 *eLevel = OMX_VIDEO_AVCLevel1b;
4143 break;
4144 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
4145 *eLevel = OMX_VIDEO_AVCLevel11;
4146 break;
4147 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
4148 *eLevel = OMX_VIDEO_AVCLevel12;
4149 break;
4150 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
4151 *eLevel = OMX_VIDEO_AVCLevel13;
4152 break;
4153 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4154 *eLevel = OMX_VIDEO_AVCLevel2;
4155 break;
4156 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4157 *eLevel = OMX_VIDEO_AVCLevel21;
4158 break;
4159 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4160 *eLevel = OMX_VIDEO_AVCLevel22;
4161 break;
4162 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4163 *eLevel = OMX_VIDEO_AVCLevel3;
4164 break;
4165 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4166 *eLevel = OMX_VIDEO_AVCLevel31;
4167 break;
4168 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4169 *eLevel = OMX_VIDEO_AVCLevel32;
4170 break;
4171 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4172 *eLevel = OMX_VIDEO_AVCLevel4;
4173 break;
4174 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4175 *eLevel = OMX_VIDEO_AVCLevel41;
4176 break;
4177 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4178 *eLevel = OMX_VIDEO_AVCLevel42;
4179 break;
4180 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4181 *eLevel = OMX_VIDEO_AVCLevel5;
4182 break;
4183 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4184 *eLevel = OMX_VIDEO_AVCLevel51;
4185 break;
4186 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4187 *eLevel = OMX_VIDEO_AVCLevel52;
4188 break;
4189 default :
4190 *eLevel = OMX_VIDEO_AVCLevelMax;
4191 status = false;
4192 break;
4193 }
4194 }
4195 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4196 switch (codec_profile.profile) {
4197 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
4198 *eProfile = OMX_VIDEO_VP8ProfileMain;
4199 break;
4200 default:
4201 *eProfile = OMX_VIDEO_VP8ProfileMax;
4202 status = false;
4203 break;
4204 }
4205 if (!status) {
4206 return status;
4207 }
4208
4209 switch (profile_level.level) {
4210 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
4211 *eLevel = OMX_VIDEO_VP8Level_Version0;
4212 break;
4213 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
4214 *eLevel = OMX_VIDEO_VP8Level_Version1;
4215 break;
4216 default:
4217 *eLevel = OMX_VIDEO_VP8LevelMax;
4218 status = false;
4219 break;
4220 }
4221 }
4222
4223 return status;
4224 }
4225
venc_validate_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)4226 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
4227 {
4228 OMX_U32 new_profile = 0, new_level = 0;
4229 unsigned const int *profile_tbl = NULL;
4230 OMX_U32 mb_per_frame, mb_per_sec;
4231 bool profile_level_found = false;
4232
4233 DEBUG_PRINT_LOW("Init profile table for respective codec");
4234
4235 //validate the ht,width,fps,bitrate and set the appropriate profile and level
4236 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
4237 if (*eProfile == 0) {
4238 if (!m_profile_set) {
4239 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4240 } else {
4241 switch (codec_profile.profile) {
4242 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
4243 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4244 break;
4245 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
4246 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4247 break;
4248 default:
4249 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4250 return false;
4251 }
4252 }
4253 }
4254
4255 if (*eLevel == 0 && !m_level_set) {
4256 *eLevel = OMX_VIDEO_MPEG4LevelMax;
4257 }
4258
4259 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
4260 profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
4261 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
4262 profile_tbl = (unsigned int const *)
4263 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
4264 } else {
4265 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
4266 return false;
4267 }
4268 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4269 if (*eProfile == 0) {
4270 if (!m_profile_set) {
4271 *eProfile = OMX_VIDEO_AVCProfileBaseline;
4272 } else {
4273 switch (codec_profile.profile) {
4274 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
4275 *eProfile = OMX_VIDEO_AVCProfileBaseline;
4276 break;
4277 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
4278 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
4279 break;
4280 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4281 *eProfile = OMX_VIDEO_AVCProfileMain;
4282 break;
4283 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4284 *eProfile = OMX_VIDEO_AVCProfileExtended;
4285 break;
4286 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4287 *eProfile = OMX_VIDEO_AVCProfileHigh;
4288 break;
4289 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4290 *eProfile = OMX_VIDEO_AVCProfileHigh10;
4291 break;
4292 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4293 *eProfile = OMX_VIDEO_AVCProfileHigh422;
4294 break;
4295 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4296 *eProfile = OMX_VIDEO_AVCProfileHigh444;
4297 break;
4298 default:
4299 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4300 return false;
4301 }
4302 }
4303 }
4304
4305 if (*eLevel == 0 && !m_level_set) {
4306 *eLevel = OMX_VIDEO_AVCLevelMax;
4307 }
4308
4309 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
4310 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
4311 profile_tbl = (unsigned int const *)h264_profile_level_table;
4312 } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
4313 profile_tbl = (unsigned int const *)
4314 (&h264_profile_level_table[H264_HP_START]);
4315 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
4316 profile_tbl = (unsigned int const *)
4317 (&h264_profile_level_table[H264_MP_START]);
4318 } else {
4319 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
4320 return false;
4321 }
4322 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
4323 if (*eProfile == 0) {
4324 if (!m_profile_set) {
4325 *eProfile = OMX_VIDEO_H263ProfileBaseline;
4326 } else {
4327 switch (codec_profile.profile) {
4328 case VEN_PROFILE_H263_BASELINE:
4329 *eProfile = OMX_VIDEO_H263ProfileBaseline;
4330 break;
4331 default:
4332 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
4333 return false;
4334 }
4335 }
4336 }
4337
4338 if (*eLevel == 0 && !m_level_set) {
4339 *eLevel = OMX_VIDEO_H263LevelMax;
4340 }
4341
4342 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
4343 profile_tbl = (unsigned int const *)h263_profile_level_table;
4344 } else {
4345 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
4346 return false;
4347 }
4348 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4349 if (*eProfile == 0) {
4350 *eProfile = OMX_VIDEO_VP8ProfileMain;
4351 } else {
4352 switch (codec_profile.profile) {
4353 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
4354 *eProfile = OMX_VIDEO_VP8ProfileMain;
4355 break;
4356 default:
4357 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
4358 return false;
4359 }
4360 }
4361 if (*eLevel == 0) {
4362 switch (profile_level.level) {
4363 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
4364 *eLevel = OMX_VIDEO_VP8Level_Version0;
4365 break;
4366 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
4367 *eLevel = OMX_VIDEO_VP8Level_Version1;
4368 break;
4369 default:
4370 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
4371 return false;
4372 }
4373 }
4374 return true;
4375 } else {
4376 DEBUG_PRINT_LOW("Invalid codec type");
4377 return false;
4378 }
4379
4380 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
4381 ((m_sVenc_cfg.dvs_width + 15)>> 4);
4382
4383 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
4384 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
4385 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4386
4387 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
4388 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
4389
4390 {
4391 new_level = profile_level.level;
4392 new_profile = codec_profile.profile;
4393 return true;
4394 }
4395 }
4396
4397 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
4398
4399 do {
4400 if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
4401 if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
4402 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
4403 new_level = (int)profile_tbl[3];
4404 new_profile = (int)profile_tbl[4];
4405 profile_level_found = true;
4406 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (unsigned int)new_profile, (unsigned int)new_level);
4407 break;
4408 }
4409 }
4410 }
4411
4412 profile_tbl = profile_tbl + 5;
4413 } while (profile_tbl[0] != 0);
4414
4415 if (profile_level_found != true) {
4416 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
4417 return false;
4418 }
4419
4420 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
4421 || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) {
4422 *eLevel = new_level;
4423 }
4424
4425 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
4426 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
4427
4428 return true;
4429 }
4430 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)4431 bool venc_dev::venc_set_meta_mode(bool mode)
4432 {
4433 metadatamode = mode;
4434 return true;
4435 }
4436 #endif
4437
venc_is_video_session_supported(unsigned long width,unsigned long height)4438 bool venc_dev::venc_is_video_session_supported(unsigned long width,
4439 unsigned long height)
4440 {
4441 if ((width * height < capability.min_width * capability.min_height) ||
4442 (width * height > capability.max_width * capability.max_height)) {
4443 DEBUG_PRINT_ERROR(
4444 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
4445 width, height, capability.min_width, capability.min_height,
4446 capability.max_width, capability.max_height);
4447 return false;
4448 }
4449
4450 DEBUG_PRINT_LOW("video session supported");
4451 return true;
4452 }
4453