1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2020 The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of The Linux Foundation nor
12       the names of its contributors may be used to endorse or promote
13       products derived from this software without specific prior written
14       permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/prctl.h>
32 #include <sys/eventfd.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include "video_encoder_device_v4l2.h"
36 #include "omx_video_encoder.h"
37 #include "media/msm_vidc_utils.h"
38 #ifdef USE_ION
39 #include <linux/msm_ion.h>
40 #endif
41 #include<linux/v4l2-controls.h>
42 
43 #include <math.h>
44 #include <media/msm_media_info.h>
45 #include <cutils/properties.h>
46 #include <media/hardware/HardwareAPI.h>
47 
48 #ifdef _ANDROID_
49 #include <media/hardware/HardwareAPI.h>
50 #include <gralloc_priv.h>
51 #endif
52 
53 #ifdef _USE_GLIB_
54 #include <glib.h>
55 #define strlcpy g_strlcpy
56 #endif
57 
58 #include <qdMetaData.h>
59 #include <color_metadata.h>
60 #include "PlatformConfig.h"
61 
62 #define ATRACE_TAG ATRACE_TAG_VIDEO
63 #include <utils/Trace.h>
64 
65 #define YUV_STATS_LIBRARY_NAME "libgpustats.so" // UBWC case: use GPU library
66 
67 #undef ALIGN
68 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
69 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
70 #define MAXDPB 16
71 #ifndef MIN
72 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
73 #endif
74 #ifndef MAX
75 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
76 #endif
77 
78 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
79 #define MAX_PROFILE_PARAMS 6
80 #define HEVC_MAIN_START 0
81 #define HEVC_MAIN10_START (HEVC_MAIN_START + 13)
82 #define POLL_TIMEOUT 1000
83 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
84 
85 #define SZ_4K 0x1000
86 #define SZ_1M 0x100000
87 
88 
89 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
90 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
91 
92 //TODO: remove once gerrit : 2680400 is merged
93 #define VIDC_HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX  HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX
94 #define VIDC_HAL_PIXEL_FORMAT_NV12_UBWC_FLEX HAL_PIXEL_FORMAT_NV12_UBWC_FLEX
95 
96 #define BUFFER_LOG_LOC "/data/vendor/media"
97 
98 #undef LOG_TAG
99 #define LOG_TAG "OMX-VENC: venc_dev"
100 
101 #define LUMINANCE_MULTIPLICATION_FACTOR 10000
102 
103 //constructor
venc_dev(class omx_venc * venc_class)104 venc_dev::venc_dev(class omx_venc *venc_class)
105 {
106     //nothing to do
107     int i = 0;
108     venc_handle = venc_class;
109     etb = ebd = ftb = fbd = 0;
110     m_poll_efd = -1;
111 
112     struct v4l2_control control;
113     for (i = 0; i < MAX_PORT; i++)
114         streaming[i] = false;
115 
116     stopped = 1;
117     paused = false;
118     async_thread_created = false;
119     async_thread_force_stop = false;
120     color_format = 0;
121     hw_overload = false;
122     mBatchSize = 0;
123     m_roi_enabled = false;
124     m_roi_type = ROI_NONE;
125     m_cvp_meta_enabled = false;
126     m_cvp_first_metadata = false;
127     low_latency_mode = false;
128     m_bDimensionsNeedFlip = false;
129     pthread_mutex_init(&m_roilock, NULL);
130     pthread_mutex_init(&m_configlock, NULL);
131     pthread_mutex_init(&pause_resume_mlock, NULL);
132     pthread_cond_init(&pause_resume_cond, NULL);
133     memset(&input_extradata_info, 0, sizeof(input_extradata_info));
134     memset(&output_extradata_info, 0, sizeof(output_extradata_info));
135     for (int i = 0; i < VIDEO_MAX_FRAME; i++) {
136         input_extradata_info.ion[i].data_fd = -1;
137         output_extradata_info.ion[i].data_fd = -1;
138     }
139     memset(&idrperiod, 0, sizeof(idrperiod));
140     memset(&multislice, 0, sizeof(multislice));
141     memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
142     memset(&rate_ctrl, 0, sizeof(rate_ctrl));
143     memset(&bitrate, 0, sizeof(bitrate));
144     memset(&intra_period, 0, sizeof(intra_period));
145     memset(&codec_profile, 0, sizeof(codec_profile));
146     memset(&set_param, 0, sizeof(set_param));
147     memset(&time_inc, 0, sizeof(time_inc));
148     memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
149     memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
150     memset(&session_qp, 0, sizeof(session_qp));
151     memset(&session_ipb_qp_values, 0, sizeof(session_ipb_qp_values));
152     memset(&entropy, 0, sizeof(entropy));
153     memset(&dbkfilter, 0, sizeof(dbkfilter));
154     memset(&intra_refresh, 0, sizeof(intra_refresh));
155     memset(&hec, 0, sizeof(hec));
156     memset(&voptimecfg, 0, sizeof(voptimecfg));
157     memset(&capability, 0, sizeof(capability));
158     memset(&m_debug,0,sizeof(m_debug));
159     sess_priority.priority = 1;
160     operating_rate = 30;
161     memset(&color_space, 0x0, sizeof(color_space));
162     memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
163     bframe_implicitly_enabled = false;
164     intra_period.num_pframes = 29;
165     intra_period.num_bframes = 0;
166     m_hdr10meta_enabled = false;
167 
168     Platform::Config::getInt32(Platform::vidc_enc_log_in,
169             (int32_t *)&m_debug.in_buffer_log, 0);
170     Platform::Config::getInt32(Platform::vidc_enc_log_out,
171             (int32_t *)&m_debug.out_buffer_log, 0);
172     Platform::Config::getInt32(Platform::vidc_enc_csc_custom_matrix,
173             (int32_t *)&is_csc_custom_matrix_enabled, 0);
174     Platform::Config::getInt32(Platform::vidc_enc_auto_blur_disable,
175             (int32_t *)&is_auto_blur_disabled, 0);
176     Platform::Config::getInt32(Platform::vidc_disable_hdr,
177             (int32_t *)&m_disable_hdr, 0);
178 
179     char property_value[PROPERTY_VALUE_MAX] = {0};
180 
181     property_get("vendor.vidc.enc.log.in", property_value, "0");
182     m_debug.in_buffer_log |= atoi(property_value);
183 
184     property_value[0] = '\0';
185     property_get("vendor.vidc.enc.log.out", property_value, "0");
186     m_debug.out_buffer_log |= atoi(property_value);
187 
188     property_get("vendor.vidc.enc.log.extradata", property_value, "0");
189     m_debug.extradata_log = atoi(property_value);
190 
191     property_get("vendor.vidc.cvp.log.in", property_value, "0");
192     m_debug.cvp_log |= atoi(property_value);
193 
194 #ifdef _UBWC_
195     property_get("vendor.gralloc.disable_ubwc", property_value, "0");
196     if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
197         !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
198         is_gralloc_source_ubwc = 0;
199     } else {
200         is_gralloc_source_ubwc = 1;
201     }
202 #else
203     is_gralloc_source_ubwc = 0;
204 #endif
205 
206      property_value[0] = '\0';
207      property_get("vendor.vidc.log.loc", property_value, BUFFER_LOG_LOC);
208      if (*property_value)
209          strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
210 
211     mUseAVTimerTimestamps = false;
212     mIsGridset = false;
213     Platform::Config::getInt32(Platform::vidc_enc_linear_color_format,
214             (int32_t *)&mUseLinearColorFormat, 0);
215     Platform::Config::getInt32(Platform::vidc_enc_bitrate_savings_enable,
216             (int32_t *)&mBitrateSavingsEnable, 3);
217     Platform::Config::getInt32(Platform::vidc_enc_quality_boost_enable,
218             (int32_t *)&mQualityBoostRequested, 0);
219     mQualityBoostEligible = false;
220 
221     profile_level_converter::init();
222 }
223 
~venc_dev()224 venc_dev::~venc_dev()
225 {
226     if (m_roi_enabled) {
227         std::list<roidata>::iterator iter;
228         pthread_mutex_lock(&m_roilock);
229         for (iter = m_roilist.begin(); iter != m_roilist.end(); iter++) {
230             DEBUG_PRINT_HIGH("roidata with timestamp (%lld) should have been removed already",
231                 iter->info.nTimeStamp);
232         }
233         m_roilist.clear();
234         mRoiRegionList.clear();
235         pthread_mutex_unlock(&m_roilock);
236     }
237     pthread_mutex_destroy(&m_roilock);
238 
239     std::list<dynamicConfig>::iterator iter;
240     pthread_mutex_lock(&m_configlock);
241     for (iter = m_configlist.begin(); iter != m_configlist.end(); iter++) {
242         DEBUG_PRINT_HIGH("dynamic config data with timestamp (%lld) should have been removed already",
243             iter->timestamp);
244     }
245     m_configlist.clear();
246     pthread_mutex_unlock(&m_configlock);
247     pthread_mutex_destroy(&m_configlock);
248 }
249 
async_venc_message_thread(void * input)250 void* venc_dev::async_venc_message_thread (void *input)
251 {
252     struct venc_msg venc_msg;
253     omx_video* omx_venc_base = NULL;
254     omx_venc *omx = reinterpret_cast<omx_venc*>(input);
255     omx_venc_base = reinterpret_cast<omx_video*>(input);
256     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
257 
258     prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
259     struct v4l2_plane plane[VIDEO_MAX_PLANES];
260     struct pollfd pfds[2];
261     struct v4l2_buffer v4l2_buf;
262     struct v4l2_event dqevent;
263     struct statistics stats;
264     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
265     pfds[1].events = POLLIN | POLLERR;
266     pfds[0].fd = omx->handle->m_nDriver_fd;
267     pfds[1].fd = omx->handle->m_poll_efd;
268     int error_code = 0,rc=0;
269 
270     memset(&stats, 0, sizeof(statistics));
271     memset(&v4l2_buf, 0, sizeof(v4l2_buf));
272 
273     while (!omx->handle->async_thread_force_stop) {
274         pthread_mutex_lock(&omx->handle->pause_resume_mlock);
275 
276         if (omx->handle->paused) {
277             venc_msg.msgcode = VEN_MSG_PAUSE;
278             venc_msg.statuscode = VEN_S_SUCCESS;
279 
280             if (omx->async_message_process(input, &venc_msg) < 0) {
281                 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
282                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
283                 break;
284             }
285 
286             /* Block here until the IL client resumes us again */
287             pthread_cond_wait(&omx->handle->pause_resume_cond,
288                     &omx->handle->pause_resume_mlock);
289 
290             venc_msg.msgcode = VEN_MSG_RESUME;
291             venc_msg.statuscode = VEN_S_SUCCESS;
292 
293             if (omx->async_message_process(input, &venc_msg) < 0) {
294                 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
295                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
296                 break;
297             }
298             memset(&stats, 0, sizeof(statistics));
299         }
300 
301         pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
302 
303         rc = poll(pfds, 2, POLL_TIMEOUT);
304 
305         if (!rc) {
306             DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
307                     omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
308             continue;
309         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
310             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
311             break;
312         }
313 
314         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
315             DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited");
316             break;
317         }
318 
319         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
320             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
321             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
322             v4l2_buf.length = omx->handle->num_output_planes;
323             v4l2_buf.m.planes = plane;
324 
325             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
326                 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
327                 venc_msg.statuscode=VEN_S_SUCCESS;
328                 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
329                 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
330                 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
331                 venc_msg.buf.flags = 0;
332                 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
333                 venc_msg.buf.clientdata=(void*)omxhdr;
334                 venc_msg.buf.timestamp = (int64_t) v4l2_buf.timestamp.tv_sec * (int64_t) 1000000 + (int64_t) v4l2_buf.timestamp.tv_usec;
335 
336                 /* TODO: ideally report other types of frames as well
337                  * for now it doesn't look like IL client cares about
338                  * other types
339                  */
340                 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
341                     venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
342                     venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
343                 }
344                 if (v4l2_buf.flags & V4L2_BUF_FLAG_PFRAME) {
345                     venc_msg.buf.flags |= OMX_VIDEO_PictureTypeP;
346                 } else if (v4l2_buf.flags & V4L2_BUF_FLAG_BFRAME) {
347                     venc_msg.buf.flags |= OMX_VIDEO_PictureTypeB;
348                 }
349 
350                 if (v4l2_buf.flags & V4L2_BUF_FLAG_CODECCONFIG)
351                     venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
352 
353                 if (v4l2_buf.flags & V4L2_BUF_FLAG_EOS)
354                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
355 
356                 if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused)
357                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
358 
359                 if (omxhdr->nFilledLen)
360                     venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
361 
362                 omx->handle->fbd++;
363                 stats.bytes_generated += venc_msg.buf.len;
364 
365                 if (omx->async_message_process(input,&venc_msg) < 0) {
366                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
367                     break;
368                 }
369             }
370         }
371 
372         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
373             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
374             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
375             v4l2_buf.m.planes = plane;
376             v4l2_buf.length = omx->handle->num_input_planes;
377 
378             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
379                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
380                 venc_msg.statuscode=VEN_S_SUCCESS;
381                 omx->handle->ebd++;
382 
383                 if (omx->handle->mBatchSize) {
384                     int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index);
385                     if (bufIndex < 0) {
386                         DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index);
387                         break;
388                     }
389                     if (omx->handle->mBatchInfo.isPending(bufIndex)) {
390                         DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending",
391                                 bufIndex, v4l2_buf.index);
392                         //do not return to client yet
393                         continue;
394                     }
395                     v4l2_buf.index = bufIndex;
396                 }
397                 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
398                     omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
399                 else
400                     omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
401 
402                 venc_msg.buf.clientdata=(void*)omxhdr;
403 
404                 DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index);
405                 if (omx->async_message_process(input,&venc_msg) < 0) {
406                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
407                     break;
408                 }
409             }
410         }
411 
412         if (pfds[0].revents & POLLPRI) {
413             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
414 
415             if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
416                 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
417                 venc_msg.statuscode = VEN_S_SUCCESS;
418 
419                 if (omx->async_message_process(input,&venc_msg) < 0) {
420                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
421                     break;
422                 }
423 
424                 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
425                 venc_msg.statuscode = VEN_S_SUCCESS;
426 
427                 if (omx->async_message_process(input,&venc_msg) < 0) {
428                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
429                     break;
430                 }
431             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
432                 DEBUG_PRINT_ERROR("HW Overload received");
433                 venc_msg.statuscode = VEN_S_EFAIL;
434                 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
435 
436                 if (omx->async_message_process(input,&venc_msg) < 0) {
437                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
438                     break;
439                 }
440             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){
441                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
442                 venc_msg.msgcode = VEN_MSG_INDICATION;
443                 venc_msg.statuscode=VEN_S_EFAIL;
444 
445                 if (omx->async_message_process(input,&venc_msg) < 0) {
446                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
447                     break;
448                 }
449             }
450         }
451 
452         /* calc avg. fps, bitrate */
453         OMX_U64 current_time;
454         OMX_U64 prev_time;
455         struct timespec curr_tv;
456         clock_gettime(CLOCK_MONOTONIC, &curr_tv);
457         current_time = (OMX_U64)curr_tv.tv_sec * 1000000000ULL + (OMX_U64)curr_tv.tv_nsec;
458         prev_time = (OMX_U64)stats.prev_tv.tv_sec * 1000000000ULL + (OMX_U64)stats.prev_tv.tv_nsec;
459         if (current_time < prev_time) {
460             stats.prev_tv = curr_tv;
461             stats.bytes_generated = 0;
462             stats.prev_fbd = omx->handle->fbd;
463         } else if (current_time - prev_time  >= 1000000000ULL) {    // timestamp is in nano_seconds
464             OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd;
465             OMX_U64 time_diff = current_time - prev_time;
466             if (stats.prev_tv.tv_sec && num_fbd && time_diff) {
467                 float framerate = ((OMX_U64)num_fbd * 1000000000ULL) / (float)time_diff;
468                 OMX_U64 bitrate = ((OMX_U64)stats.bytes_generated * 8 / (float)num_fbd) * framerate;
469                 DEBUG_PRINT_INFO("stats: avg. fps %0.2f, bitrate %llu",
470                     framerate, bitrate);
471             }
472             stats.prev_tv = curr_tv;
473             stats.bytes_generated = 0;
474             stats.prev_fbd = omx->handle->fbd;
475         }
476 
477     }
478 
479     DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
480     return NULL;
481 }
482 
483 static const int event_type[] = {
484     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
485     V4L2_EVENT_MSM_VIDC_SYS_ERROR
486 };
487 
subscribe_to_events(int fd)488 static OMX_ERRORTYPE subscribe_to_events(int fd)
489 {
490     OMX_ERRORTYPE eRet = OMX_ErrorNone;
491     struct v4l2_event_subscription sub;
492     int array_sz = sizeof(event_type)/sizeof(int);
493     int i,rc;
494     memset(&sub, 0, sizeof(sub));
495 
496     if (fd < 0) {
497        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
498         return OMX_ErrorBadParameter;
499     }
500 
501     for (i = 0; i < array_sz; ++i) {
502         memset(&sub, 0, sizeof(sub));
503         sub.type = event_type[i];
504         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
505 
506         if (rc) {
507            DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
508             break;
509         }
510     }
511 
512     if (i < array_sz) {
513         for (--i; i >=0 ; i--) {
514             memset(&sub, 0, sizeof(sub));
515             sub.type = event_type[i];
516             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
517 
518             if (rc)
519                DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
520         }
521 
522         eRet = OMX_ErrorNotImplemented;
523     }
524 
525     return eRet;
526 }
527 
venc_query_cap(struct v4l2_queryctrl & cap)528 bool inline venc_dev::venc_query_cap(struct v4l2_queryctrl &cap) {
529 
530     if (ioctl(m_nDriver_fd, VIDIOC_QUERYCTRL, &cap)) {
531         DEBUG_PRINT_ERROR("Query caps for id = %u failed", cap.id);
532         return false;
533     }
534     return true;
535 }
536 
venc_validate_range(OMX_S32 id,OMX_S32 val)537 bool venc_dev::venc_validate_range(OMX_S32 id, OMX_S32 val) {
538 
539     struct v4l2_queryctrl cap;
540     memset(&cap, 0, sizeof(struct v4l2_queryctrl));
541 
542     cap.id = id;
543     if (venc_query_cap(cap)) {
544         if (val >= cap.minimum && val <= cap.maximum) {
545             return true;
546         } else {
547             DEBUG_PRINT_INFO("id = %u, value = %u, min = %u, max = %u",
548                 cap.id, val, cap.minimum, cap.maximum);
549         }
550     }
551     return false;
552 }
553 
get_roi_for_timestamp(struct roidata & roi,OMX_TICKS timestamp)554 void venc_dev::get_roi_for_timestamp(struct roidata &roi, OMX_TICKS timestamp)
555 {
556     std::list<roidata>::iterator iter;
557     bool found = false;
558 
559     memset(&roi, 0, sizeof(struct roidata));
560     roi.dirty = false;
561 
562     pthread_mutex_lock(&m_roilock);
563     iter = m_roilist.begin();
564     while (iter != m_roilist.end()) {
565         if (iter->info.nTimeStamp < timestamp) {
566             /* remove previous roi data */
567             iter = m_roilist.erase(iter);
568             /* iter++ is not required as erase would do it */
569             continue;
570         } else if (iter->info.nTimeStamp == timestamp){
571             found = true;
572             roi = *iter;
573             break;
574         }
575         iter++;
576     }
577     if (found) {
578         DEBUG_PRINT_LOW("found roidata with timestamp %lld us", roi.info.nTimeStamp);
579     }
580     pthread_mutex_unlock(&m_roilock);
581 }
582 
handle_dynamic_config(OMX_BUFFERHEADERTYPE * bufferHdr)583 bool venc_dev::handle_dynamic_config(OMX_BUFFERHEADERTYPE *bufferHdr)
584 {
585     std::list<dynamicConfig>::iterator iter;
586     OMX_TICKS timestamp = bufferHdr->nTimeStamp;
587     bool ret = false;
588 
589     pthread_mutex_lock(&m_configlock);
590     iter = m_configlist.begin();
591     while (iter != m_configlist.end()) {
592         if (iter->timestamp > timestamp) {
593             iter++;
594             continue;
595         }
596         DEBUG_PRINT_LOW("found dynamic config with timestamp %lld us", iter->timestamp);
597         switch ((int)iter->type) {
598             case OMX_QcomIndexConfigVideoLTRUse:
599                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_QcomIndexConfigVideoLTRUse");
600                 if (!venc_config_useLTR(&iter->config_data.useltr))
601                     goto bailout;
602                 break;
603             case OMX_QcomIndexConfigVideoLTRMark:
604                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_QcomIndexConfigVideoLTRMark");
605                 if (!venc_config_markLTR(&iter->config_data.markltr))
606                     goto bailout;
607                 break;
608             case OMX_IndexConfigVideoFramerate:
609                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_IndexConfigVideoFramerate");
610                 if (!venc_config_framerate(&iter->config_data.framerate))
611                     goto bailout;
612                 break;
613             case OMX_QcomIndexConfigQp:
614                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_QcomIndexConfigQp");
615                 if (!venc_config_qp(&iter->config_data.configqp))
616                     goto bailout;
617                 break;
618             case QOMX_IndexConfigVideoIntraperiod:
619                 DEBUG_PRINT_LOW("handle_dynamic_config:QOMX_IndexConfigVideoIntraperiod");
620                 if (!set_nP_frames(iter->config_data.intraperiod.nPFrames))
621                     goto bailout;
622                 break;
623             case OMX_IndexConfigVideoVp8ReferenceFrame:
624                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_IndexConfigVideoVp8ReferenceFrame");
625                 if (!venc_config_vp8refframe(&iter->config_data.vp8refframe))
626                     goto bailout;
627                 break;
628             case OMX_IndexConfigVideoIntraVOPRefresh:
629                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_IndexConfigVideoIntraVOPRefresh");
630                 if (!venc_config_intravoprefresh(&iter->config_data.intravoprefresh))
631                     goto bailout;
632                 break;
633             case OMX_IndexConfigVideoBitrate:
634                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_IndexConfigVideoBitrate");
635                 if (!venc_config_bitrate(&iter->config_data.bitrate))
636                     goto bailout;
637                 break;
638             case OMX_IndexConfigCommonMirror:
639                 DEBUG_PRINT_LOW("handle_dynamic_config: OMX_IndexConfigCommonMirror");
640                 if (!strncmp(venc_handle->m_platform, "bengal", 6) && (venc_handle->m_no_vpss)) {
641                     DEBUG_PRINT_HIGH("Unsupported dynamic config on this target");
642                     ret = true;
643                     goto bailout;
644                 } else if (!venc_set_mirror(iter->config_data.mirror.eMirror)) {
645                     goto bailout;
646                 }
647                 break;
648             default:
649                 DEBUG_PRINT_ERROR("Unsupported dynamic config type %d with timestamp %lld us", iter->type, iter->timestamp);
650                 goto bailout;
651         }
652         iter = m_configlist.erase(iter);
653     }
654     ret = true;
655 
656 bailout:
657     pthread_mutex_unlock(&m_configlock);
658     return ret;
659 }
660 
handle_input_extradata(struct v4l2_buffer buf)661 bool venc_dev::handle_input_extradata(struct v4l2_buffer buf)
662 {
663     unsigned int filled_len = 0;
664     unsigned int index = buf.index;
665     int height = m_sVenc_cfg.input_height;
666     int width = m_sVenc_cfg.input_width;
667     OMX_TICKS nTimeStamp = static_cast<OMX_TICKS>(buf.timestamp.tv_sec) * 1000000 + buf.timestamp.tv_usec;
668     int fd = buf.m.planes[0].reserved[MSM_VIDC_BUFFER_FD];
669     char *p_extradata = NULL;
670     OMX_OTHER_EXTRADATATYPE *data = NULL;
671     struct roidata roi;
672     bool status = true;
673     OMX_U32 packet_size = 0;
674     OMX_U32 payload_size = 0;
675 
676     if (!EXTRADATA_IDX(num_input_planes)) {
677         DEBUG_PRINT_LOW("Input extradata not enabled");
678         return true;
679     }
680 
681     if (!input_extradata_info.ion[index].uaddr) {
682         DEBUG_PRINT_ERROR("Extradata buffers not allocated\n");
683         return true;
684     }
685 
686     DEBUG_PRINT_HIGH("Processing Extradata for Buffer = %lld", nTimeStamp); // Useful for debugging
687     sync_start_rw(input_extradata_info.ion[index].data_fd);
688 
689     p_extradata = input_extradata_info.ion[index].uaddr;
690     data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
691     memset((void *)(data), 0, (input_extradata_info.buffer_size)); // clear stale data in current buffer
692 
693     if (m_cvp_meta_enabled && !(buf.flags & V4L2_BUF_FLAG_CVPMETADATA_SKIP)) {
694         packet_size = sizeof(struct msm_vidc_extradata_header) - sizeof(unsigned int)
695                            + cvpMetadata.size;
696 
697         if (filled_len + packet_size <= input_extradata_info.buffer_size) {
698             struct  msm_vidc_enc_cvp_metadata_payload *payload_cvp;
699             data->nSize = ALIGN(packet_size, 4);
700             data->nVersion.nVersion = OMX_SPEC_VERSION;
701             data->nPortIndex = PORT_INDEX_IN;
702             data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_CVP_METADATA;
703             data->nDataSize = cvpMetadata.size;
704             payload_cvp = (struct  msm_vidc_enc_cvp_metadata_payload *)(data->data);
705             memcpy(payload_cvp->data, cvpMetadata.payload, cvpMetadata.size);
706             filled_len += data->nSize;
707             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
708         } else {
709             DEBUG_PRINT_ERROR("Insufficient size for CVPMetadata: required %u buffer_size %lu filled_len %u",
710                packet_size, input_extradata_info.buffer_size, filled_len);
711             status = false;
712             goto bailout;
713         }
714     }
715     cvpMetadata.size = 0;
716 
717       /*
718        * Below code is based on these points.
719        * 1) As _PQ_ not defined in Napali :
720        *     a) Send data to Venus as ROI.
721        *     b) ROI enabled : Processed under unlocked context.
722        *     c) ROI disabled : Nothing to fill.
723        *     d) pq enabled : Not possible.
724        * 2) Normal ROI handling.
725        *     By this time if client sets next ROI, then we shouldn't process new ROI here.
726        */
727 
728     memset(&roi, 0, sizeof(struct roidata));
729     roi.dirty = false;
730     if (m_roi_enabled) {
731         get_roi_for_timestamp(roi, nTimeStamp);
732     }
733 
734     if (roi.dirty) {
735         OMX_U32 mbAlign = 16;
736         if (m_codec == OMX_VIDEO_CodingHEVC) {
737             mbAlign = 32;
738         }
739         OMX_U32 mbRow = ALIGN(width, mbAlign) / mbAlign;
740         OMX_U32 mbRowAligned = ((mbRow + 7) >> 3) << 3;
741         OMX_U32 mbCol = ALIGN(height, mbAlign) / mbAlign;
742         OMX_U32 numBytes = mbRowAligned * mbCol * 2;
743         OMX_U32 numBytesAligned = ALIGN(numBytes, 4);
744 
745         data->nDataSize = ALIGN(sizeof(struct msm_vidc_roi_deltaqp_payload),256)
746                             + numBytesAligned;
747         data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + data->nDataSize, 4);
748         if (data->nSize > input_extradata_info.buffer_size  - filled_len) {
749            DEBUG_PRINT_ERROR("Buffer size (%lu) is less than ROI extradata size (%u)",
750                              (input_extradata_info.buffer_size - filled_len) ,data->nSize);
751            status = false;
752            goto bailout;
753         }
754 
755         data->nVersion.nVersion = OMX_SPEC_VERSION;
756         data->nPortIndex = 0;
757         data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
758         struct msm_vidc_roi_deltaqp_payload *roiData =
759                 (struct msm_vidc_roi_deltaqp_payload *)(data->data);
760         roiData->b_roi_info = true;
761         roiData->mbi_info_size = numBytesAligned;
762         /* Video hardware expects ROI QP data to be aligned to 256,
763          * And its offset should be available in roiData->data[0].
764          *  -----------------
765          *  | unsigned int b_roi_info;   |
766          *  | int mbi_info_size;         |
767          *  ----------------------------
768          *  | data[0] = n                | => Contains Offset value to 256 aligned address
769          *  | .                          |
770          *  | .                          |
771          *  | .                          |
772          *  | data+n  <ROI data start>   | => 256 aligned address
773          *  ----------------------------
774          */
775         roiData->data[0] = (unsigned int)(ALIGN(&roiData->data[1], 256) - (unsigned long)roiData->data);
776 
777         OMX_U8* tempBuf = (OMX_U8*)roi.info.pRoiMBInfo;
778         OMX_U16* exDataBuf = (OMX_U16*)((OMX_U8*)roiData->data + roiData->data[0]);;
779         OMX_U16* pBuf;
780         OMX_U8 clientROI;
781 
782         /* Convert input extradata format to HW compatible format
783          * Input        : 1byte per MB
784          * HW Format    : 2bytes per MB. (1 << 11) | ((clientROI & 0x3F)<< 4)
785          * MB Row must be aligned to 8
786          */
787         for (OMX_U32 j = 0;j < mbCol; j++)
788         {
789             pBuf = exDataBuf + j*mbRowAligned;
790             for (OMX_U32 i = 0;i < mbRow; i++)
791             {
792                 clientROI = *tempBuf++;
793                 *pBuf++ = (1 << 11) | ((clientROI & 0x3F)<< 4);
794             }
795         }
796         filled_len += data->nSize;
797         data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
798     } else {
799         // m_roilist didn't contain any ROI info with OMX_IndexConfigVideoRoiInfo.
800         // then we can check mRoiRegionList which may contain the roi from vendor extension.
801         OMX_U32 freeSize = input_extradata_info.buffer_size - filled_len;
802         OMX_U32 appendSize = append_extradata_roi_region_qp_info(data, nTimeStamp, freeSize);
803         filled_len += appendSize;
804         data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + appendSize);
805     }
806 
807     if (m_roi_enabled) {
808         if (roi.dirty) {
809             DEBUG_PRINT_LOW("free roidata with timestamp %lld us", roi.info.nTimeStamp);
810             roi.dirty = false;
811         }
812     }
813 
814     /* HDR10Plus MetaData information. Enabled by Default. */
815     payload_size = sizeof(struct msm_vidc_hdr10plus_metadata_payload) - sizeof(unsigned int)
816                                 + colorData.dynamicMetaDataLen;
817     packet_size = (sizeof(OMX_OTHER_EXTRADATATYPE) + payload_size + 3)&(~3);
818 
819     if (m_hdr10meta_enabled && (filled_len + packet_size <= input_extradata_info.buffer_size) && colorData.dynamicMetaDataLen > 0) {
820         struct msm_vidc_hdr10plus_metadata_payload *payload;
821 
822         data->nSize = packet_size;
823         data->nVersion.nVersion = OMX_SPEC_VERSION;
824         data->nPortIndex = 0;
825         data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_HDR10PLUS_METADATA;
826         data->nDataSize = payload_size;
827 
828         payload = (struct  msm_vidc_hdr10plus_metadata_payload *)(data->data);
829         payload->size = colorData.dynamicMetaDataLen;
830         memcpy(payload->data, colorData.dynamicMetaDataPayload, colorData.dynamicMetaDataLen);
831 
832         filled_len += data->nSize;
833         data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
834     } else if (colorData.dynamicMetaDataLen == 0) {
835         DEBUG_PRINT_HIGH("DynamicMetaDataLength == 0 Skip writing metadata.");
836     } else {
837         if (m_hdr10meta_enabled) {
838             DEBUG_PRINT_HIGH("Insufficient size for HDR10Metadata: Required %u Available %lu",
839                              packet_size, (input_extradata_info.buffer_size - filled_len));
840         }
841     }
842 
843     data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
844     data->nVersion.nVersion = OMX_SPEC_VERSION;
845     data->eType = OMX_ExtraDataNone;
846     data->nDataSize = 0;
847     data->data[0] = 0;
848 
849 bailout:
850     sync_end_rw(input_extradata_info.ion[index].data_fd);
851     return status;
852 }
853 
venc_handle_client_input_extradata(void * buffer)854 bool venc_dev::venc_handle_client_input_extradata(void *buffer)
855 {
856     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
857     OMX_OTHER_EXTRADATATYPE *p_extra = (OMX_OTHER_EXTRADATATYPE*)p_bufhdr->pBuffer;
858     while(p_extra->eType != OMX_ExtraDataNone) {
859         switch((int)p_extra->eType) {
860             case OMX_ExtraDataInputROIInfo:
861             {
862                 OMX_QTI_VIDEO_CONFIG_ROIINFO* roiInfo = reinterpret_cast<OMX_QTI_VIDEO_CONFIG_ROIINFO*>(p_extra->data);
863                 struct roidata roi;
864                 if (!m_roi_enabled) {
865                     DEBUG_PRINT_ERROR("ROI info not enabled");
866                     return false;
867                 }
868 
869                 if (!roiInfo) {
870                     DEBUG_PRINT_ERROR("No ROI info present");
871                     return false;
872                 }
873                 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
874                 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
875                     DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %d codec", (OMX_U32) m_sVenc_cfg.codectype);
876                     return false;
877                 }
878 
879                 memset(&roi, 0, sizeof(struct roidata));
880 
881                 roi.info.nRoiMBInfoCount = roiInfo->nRoiMBInfoCount;
882                 roi.info.nTimeStamp = roiInfo->nTimeStamp;
883                 memcpy(roi.info.pRoiMBInfo, &roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoCount);
884 
885                 roi.dirty = true;
886 
887                 pthread_mutex_lock(&m_roilock);
888                 DEBUG_PRINT_LOW("list add roidata with timestamp %lld us.", roi.info.nTimeStamp);
889                 m_roilist.push_back(roi);
890                 pthread_mutex_unlock(&m_roilock);
891                 break;
892             }
893         }
894         p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize);
895     }
896     return true;
897 }
898 
handle_output_extradata(void * buffer,int index)899 bool venc_dev::handle_output_extradata(void *buffer, int index)
900 {
901     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
902     OMX_OTHER_EXTRADATATYPE *p_clientextra = NULL;
903     struct msm_vidc_extradata_header *p_extradata = NULL;
904     OMX_U32 remaining_fw_extradata_size = 0;
905 
906     if(venc_handle->m_client_output_extradata_mem_ptr && venc_handle->m_sExtraData
907         && venc_handle->m_client_out_extradata_info.getSize() >=
908         output_extradata_info.buffer_size) {
909         p_clientextra = (OMX_OTHER_EXTRADATATYPE * )
910             ((venc_handle->m_client_output_extradata_mem_ptr + index) ->pBuffer);
911     }
912     if (p_clientextra == NULL) {
913         DEBUG_PRINT_ERROR("Client Extradata buffers not allocated\n");
914         return false;
915     }
916 
917     if (!output_extradata_info.ion[index].uaddr) {
918         DEBUG_PRINT_ERROR("Extradata buffers not allocated\n");
919         return false;
920     }
921     p_extradata = (struct msm_vidc_extradata_header *)output_extradata_info.ion[index].uaddr;
922 
923     memcpy(p_clientextra, p_extradata, output_extradata_info.buffer_size);
924 
925     /* just for debugging */
926     remaining_fw_extradata_size = output_extradata_info.buffer_size;
927     while (remaining_fw_extradata_size >= sizeof(OMX_OTHER_EXTRADATATYPE) &&
928             remaining_fw_extradata_size >= p_extradata->size &&
929             p_extradata->type != MSM_VIDC_EXTRADATA_NONE) {
930 
931         switch (p_extradata->type) {
932             case MSM_VIDC_EXTRADATA_METADATA_LTRINFO:
933             {
934                 DEBUG_PRINT_LOW("LTRInfo Extradata = 0x%x", *((OMX_U32 *)p_extradata->data));
935                 break;
936             }
937             default:
938                 /* No idea what this stuff is, just skip over it */
939                 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
940                         p_extradata->type);
941                 break;
942         }
943 
944         remaining_fw_extradata_size -= p_extradata->size;
945         p_extradata = (struct msm_vidc_extradata_header *) (
946             ((char *)p_extradata) + p_extradata->size);
947     }
948 
949     return true;
950 }
951 
venc_set_format(int format)952 int venc_dev::venc_set_format(int format)
953 {
954     int rc = true;
955 
956     if (format) {
957         color_format = format;
958 
959         switch (color_format) {
960         case NV12_128m:
961         case NV12_512:
962             return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m);
963         case NV12_UBWC:
964             return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed);
965         case YCbCr420_VENUS_P010:
966             return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus);
967         default:
968             return false;
969         }
970 
971     } else {
972         color_format = 0;
973         rc = false;
974     }
975 
976     return rc;
977 }
978 
venc_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)979 OMX_ERRORTYPE venc_dev::venc_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
980 {
981     OMX_ERRORTYPE eRet = OMX_ErrorNone;
982     struct v4l2_queryctrl profile_cap, level_cap, tier_cap;
983     int v4l2_profile;
984     char platform_name[PROP_VALUE_MAX] = {0};
985     char version[PROP_VALUE_MAX] = {0};
986 
987     int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
988                             QOMX_VIDEO_AVCProfileBaseline,
989                             QOMX_VIDEO_AVCProfileMain,
990                             QOMX_VIDEO_AVCProfileConstrainedHigh,
991                             QOMX_VIDEO_AVCProfileHigh };
992     int hevc_profiles[5] = { OMX_VIDEO_HEVCProfileMain,
993                              OMX_VIDEO_HEVCProfileMain10,
994                              OMX_VIDEO_HEVCProfileMainStill,
995                              OMX_VIDEO_HEVCProfileMain10HDR10,
996                              OMX_VIDEO_HEVCProfileMain10HDR10Plus };
997 
998     if (!profileLevelType)
999         return OMX_ErrorBadParameter;
1000 
1001     memset(&tier_cap, 0, sizeof(struct v4l2_queryctrl));
1002     memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
1003     memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
1004 
1005     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1006         level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
1007         profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
1008     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1009         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
1010         profile_cap.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
1011     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1012         tier_cap.id = V4L2_CID_MPEG_VIDEO_HEVC_TIER;
1013         level_cap.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
1014         profile_cap.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
1015     } else {
1016         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
1017         return OMX_ErrorInvalidComponent;
1018     }
1019 
1020     if (profile_cap.id) {
1021         if(!venc_query_cap(profile_cap)) {
1022             DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
1023             return OMX_ErrorHardware;
1024         }
1025     }
1026 
1027     if (level_cap.id) {
1028         if(!venc_query_cap(level_cap)) {
1029             DEBUG_PRINT_ERROR("Getting capabilities for level failed");
1030             return OMX_ErrorHardware;
1031         }
1032     }
1033 
1034     if (tier_cap.id) {
1035         if(!venc_query_cap(tier_cap)) {
1036             DEBUG_PRINT_ERROR("Getting capabilities for tier failed");
1037             return OMX_ErrorHardware;
1038         }
1039     }
1040 
1041     /* Get the corresponding omx level from v4l2 level */
1042     if (!profile_level_converter::convert_v4l2_level_to_omx(m_sVenc_cfg.codectype, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
1043         DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
1044         return OMX_ErrorHardware;
1045     }
1046     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && tier_cap.maximum == V4L2_MPEG_VIDEO_HEVC_TIER_HIGH) {
1047         /* handle HEVC high tier */
1048         profileLevelType->eLevel <<= 1;
1049     }
1050 
1051     /* For given profile index get corresponding profile that needs to be supported */
1052     if (profileLevelType->nPortIndex != 1) {
1053         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on output port only %u",
1054                             (unsigned int)profileLevelType->nPortIndex);
1055         return OMX_ErrorBadPortIndex;
1056     }
1057 
1058     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1059         if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
1060             profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
1061         } else {
1062             DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
1063                     (unsigned int)profileLevelType->nProfileIndex);
1064             return OMX_ErrorNoMore;
1065         }
1066     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1067         if (profileLevelType->nProfileIndex == 0) {
1068             profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
1069         } else {
1070             DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
1071                     (unsigned int)profileLevelType->nProfileIndex);
1072             return OMX_ErrorNoMore;
1073         }
1074     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1075         if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
1076             profileLevelType->eProfile =  hevc_profiles[profileLevelType->nProfileIndex];
1077         } else {
1078             DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
1079                     (unsigned int)profileLevelType->nProfileIndex);
1080             return OMX_ErrorNoMore;
1081         }
1082     }
1083 
1084     /* Check if the profile is supported by driver or not  */
1085     /* During query caps of profile driver sends a mask of */
1086     /* of all v4l2 profiles supported(in the flags field)  */
1087     if (!profile_level_converter::convert_omx_profile_to_v4l2(m_sVenc_cfg.codectype, profileLevelType->eProfile, &v4l2_profile)) {
1088         DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
1089         return OMX_ErrorHardware;
1090     }
1091 
1092     DEBUG_PRINT_INFO("v4l2 profile : %d flags : %d ", v4l2_profile, profile_cap.flags);
1093     if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
1094         DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
1095         eRet = OMX_ErrorNoMore;
1096     }
1097 
1098     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1099         property_get("ro.board.platform", platform_name, "0");
1100         if (!strncmp(platform_name, "lito", 4)) {
1101             if (property_get("vendor.media.target.version", version, "0") && ((atoi(version) != 2) && (atoi(version) != 3))) {
1102                 DEBUG_PRINT_LOW("Disabling main10 and above for saipan");
1103                 m_disable_hdr = 0x2;
1104             }
1105         }
1106     }
1107 
1108     if (m_disable_hdr & ENC_HDR_DISABLE_FLAG) {
1109         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1110             if (profileLevelType->eProfile == OMX_VIDEO_HEVCProfileMain10 ||
1111                 profileLevelType->eProfile == OMX_VIDEO_HEVCProfileMain10HDR10 ||
1112                 profileLevelType->eProfile == OMX_VIDEO_HEVCProfileMain10HDR10Plus) {
1113                 DEBUG_PRINT_LOW("%s: HDR profile unsupported", __FUNCTION__);
1114                 return OMX_ErrorHardware;
1115             }
1116         }
1117     }
1118 
1119     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
1120             (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
1121     return eRet;
1122 }
1123 
venc_get_supported_color_format(unsigned index,OMX_U32 * colorFormat)1124 bool venc_dev::venc_get_supported_color_format(unsigned index, OMX_U32 *colorFormat) {
1125 #ifdef _UBWC_
1126     //we support following formats
1127     //index 0 - Compressed (UBWC) Venus flavour of YUV420SP
1128     //index 1 - Venus flavour of YUV420SP
1129     //index 2 - Compressed (UBWC) TP10 (10bit packed)
1130     //index 3 - Compressed (UBWC) Venus flavour of RGBA8888
1131     //index 4 - Venus flavour of RGBA8888
1132     //index 5 - opaque which internally maps to YUV420SP.
1133     //index 6 - vannilla YUV420SP
1134     //this can be extended in the future
1135     int supportedFormats[] = {
1136         [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
1137         [1] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
1138         [2] = QOMX_COLOR_FormatYVU420SemiPlanar,
1139         [3] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed,
1140         [4] = QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus,
1141         [5] = QOMX_COLOR_Format32bitRGBA8888Compressed,
1142         [6] = QOMX_COLOR_Format32bitRGBA8888,
1143         [7] = QOMX_COLOR_FormatAndroidOpaque,
1144         [8] = OMX_COLOR_FormatYUV420SemiPlanar,
1145     };
1146 #else
1147     //we support two formats
1148     //index 0 - Venus flavour of YUV420SP
1149     //index 1 - opaque which internally maps to YUV420SP.
1150     //index 2 - vannilla YUV420SP
1151     //this can be extended in the future
1152     int supportedFormats[] = {
1153         [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
1154         [1] = QOMX_COLOR_FormatYVU420SemiPlanar,
1155         [2] = QOMX_COLOR_FormatAndroidOpaque,
1156         [3] = OMX_COLOR_FormatYUV420SemiPlanar,
1157     };
1158 #endif
1159     if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
1160         return false;
1161     *colorFormat = supportedFormats[index];
1162     return true;
1163 }
1164 
allocate_extradata(struct extradata_buffer_info * extradata_info,int flags)1165 OMX_ERRORTYPE venc_dev::allocate_extradata(struct extradata_buffer_info *extradata_info, int flags)
1166 {
1167     if (extradata_info->allocated)
1168         return OMX_ErrorNone;
1169 
1170     if (!extradata_info->buffer_size || !extradata_info->count) {
1171         DEBUG_PRINT_ERROR("Invalid extradata buffer size(%lu) or count(%d) for port %d",
1172             extradata_info->buffer_size, extradata_info->count, extradata_info->port_index);
1173         return OMX_ErrorUndefined;
1174     }
1175 
1176 #ifdef USE_ION
1177 
1178     for (int i = 0; i < extradata_info->count; i++) {
1179         if (extradata_info->ion[i].data_fd != -1) {
1180             venc_handle->ion_unmap(extradata_info->ion[i].data_fd,
1181                     (void *)extradata_info->ion[i].uaddr, extradata_info->buffer_size);
1182             venc_handle->free_ion_memory(&extradata_info->ion[i]);
1183         }
1184 
1185         // ION_IOC_MAP defined @ bionic/libc/kernel/uapi/linux/ion.h not in kernel,
1186         // and this ioctl uses "struct ion_fd_data" with handle member
1187         // Refer alloc_map_ion_memory definition @omx_video_base.cpp
1188         bool status = venc_handle->alloc_map_ion_memory(
1189                 extradata_info->buffer_size, &extradata_info->ion[i], flags);
1190 
1191         if (status == false) {
1192             DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
1193             return OMX_ErrorInsufficientResources;
1194         }
1195 
1196         extradata_info->ion[i].uaddr = (char *)venc_handle->ion_map(extradata_info->ion[i].data_fd,
1197                                                 extradata_info->buffer_size);
1198 
1199         if (extradata_info->ion[i].uaddr == MAP_FAILED) {
1200             DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
1201             venc_handle->free_ion_memory(&extradata_info->ion[i]);
1202             return OMX_ErrorInsufficientResources;
1203         } else {
1204             DEBUG_PRINT_HIGH("memset extradata buffer size %lu", extradata_info->buffer_size);
1205             memset((char *)extradata_info->ion[i].uaddr, 0, extradata_info->buffer_size);
1206         }
1207     }
1208 #else
1209     (void)flags;
1210 #endif
1211     extradata_info->allocated = OMX_TRUE;
1212     return OMX_ErrorNone;
1213 }
1214 
free_extradata(struct extradata_buffer_info * extradata_info)1215 void venc_dev::free_extradata(struct extradata_buffer_info *extradata_info)
1216 {
1217 #ifdef USE_ION
1218 
1219     if (extradata_info == NULL) {
1220         return;
1221     }
1222 
1223     for (int i = 0; i < extradata_info->count; i++) {
1224         if (extradata_info->ion[i].uaddr) {
1225             venc_handle->ion_unmap(extradata_info->ion[i].data_fd,
1226                     (void *)extradata_info->ion[i].uaddr, extradata_info->buffer_size);
1227             extradata_info->ion[i].uaddr = NULL;
1228             venc_handle->free_ion_memory(&extradata_info->ion[i]);
1229         }
1230         memset(&extradata_info->ion[i].alloc_data, 0, sizeof(struct ion_allocation_data));
1231     }
1232     extradata_info->buffer_size = 0;
1233     extradata_info->count = 0;
1234     extradata_info->allocated = OMX_FALSE;
1235 #else
1236     (void)extradata_info;
1237 #endif // USE_ION
1238 }
1239 
free_extradata_all()1240 void venc_dev::free_extradata_all()
1241 {
1242     free_extradata(&output_extradata_info);
1243     free_extradata(&input_extradata_info);
1244 }
1245 
venc_get_output_log_flag()1246 bool venc_dev::venc_get_output_log_flag()
1247 {
1248     return (m_debug.out_buffer_log == 1);
1249 }
1250 
venc_cvp_log_buffers(const char * metadataName,uint32_t buffer_len,uint8_t * buf)1251 int venc_dev::venc_cvp_log_buffers(const char *metadataName, uint32_t buffer_len, uint8_t *buf)
1252 {
1253     if (!m_debug.cvpfile && m_debug.cvp_log) {
1254         int size = 0;
1255 
1256         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
1257             m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1258                 size = snprintf(m_debug.cvpfile_name, PROPERTY_VALUE_MAX, "%s/enc_cvp_%lu_%lu_%p.bin",
1259                         m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1260         }
1261 
1262         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
1263             DEBUG_PRINT_ERROR("Failed to open cvp file: %s for logging size:%d",
1264                     m_debug.cvpfile_name, size);
1265         }
1266 
1267         m_debug.cvpfile = fopen(m_debug.cvpfile_name, "ab");
1268         if (!m_debug.cvpfile) {
1269             DEBUG_PRINT_ERROR("Failed to open cvp file: %s for logging errno:%d",
1270                             m_debug.cvpfile_name, errno);
1271             m_debug.cvpfile_name[0] = '\0';
1272             return -1;
1273         }
1274     }
1275 
1276     if (m_debug.cvpfile) {
1277         // Truncate or Zero-filled to match the string size to 5
1278         char name[6] = {0};
1279         for(int i=0; i<5 && i<strlen(metadataName); i++) {
1280             name[i] = metadataName[i];
1281         }
1282         fwrite(name, 5, 1, m_debug.cvpfile);                            // Metadata name
1283         fwrite(&buffer_len, sizeof(buffer_len), 1, m_debug.cvpfile);    // Blob size
1284         fwrite(buf, buffer_len, 1, m_debug.cvpfile);                    // Blob data
1285     }
1286     return 0;
1287 }
1288 
1289 
venc_output_log_buffers(const char * buffer_addr,int buffer_len,uint64_t timestamp)1290 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len, uint64_t timestamp)
1291 {
1292     if (venc_handle->is_secure_session()) {
1293         DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
1294         return -1;
1295     }
1296 
1297     if (!m_debug.outfile) {
1298         int size = 0;
1299         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
1300            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
1301                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1302         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
1303            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
1304                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1305         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1306            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
1307                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1308         }
1309 
1310         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
1311              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
1312                                 m_debug.outfile_name, size);
1313         }
1314         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
1315         if (!m_debug.outfile) {
1316             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
1317                                m_debug.outfile_name, errno);
1318             m_debug.outfile_name[0] = '\0';
1319             return -1;
1320         }
1321         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1322             int fps = m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
1323             IvfFileHeader ivfFileHeader(false, m_sVenc_cfg.input_width,
1324                                         m_sVenc_cfg.input_height, fps, 1, 0);
1325             fwrite(&ivfFileHeader, sizeof(ivfFileHeader), 1, m_debug.outfile);
1326         }
1327     }
1328     if (m_debug.outfile && buffer_len) {
1329         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1330             IvfFrameHeader ivfFrameHeader(buffer_len, timestamp);
1331             fwrite(&ivfFrameHeader, sizeof(ivfFrameHeader), 1, m_debug.outfile);
1332         }
1333         DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
1334         fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
1335     }
1336     return 0;
1337 }
1338 
venc_extradata_log_buffers(char * buffer_addr,int index,bool input)1339 int venc_dev::venc_extradata_log_buffers(char *buffer_addr, int index, bool input)
1340 {
1341     int fd;
1342 
1343     if (input)
1344         fd = input_extradata_info.ion[index].data_fd;
1345     else
1346         fd = output_extradata_info.ion[index].data_fd;
1347 
1348     sync_start_read(fd);
1349     if (!m_debug.extradatafile && m_debug.extradata_log) {
1350         int size = 0;
1351 
1352         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
1353             m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC ||
1354             m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1355             size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
1356                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1357         }
1358         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
1359              DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
1360                                 m_debug.extradatafile_name, size);
1361         }
1362 
1363         m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
1364         if (!m_debug.extradatafile) {
1365             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
1366                                m_debug.extradatafile_name, errno);
1367             m_debug.extradatafile_name[0] = '\0';
1368             sync_end_read(fd);
1369             return -1;
1370         }
1371     }
1372 
1373     if (m_debug.extradatafile && buffer_addr) {
1374         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
1375         do {
1376             p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
1377                     ((char *)p_extra) + p_extra->nSize);
1378             fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
1379         } while (p_extra->eType != OMX_ExtraDataNone);
1380     }
1381     sync_end_read(fd);
1382     return 0;
1383 }
1384 
venc_input_log_buffers(OMX_BUFFERHEADERTYPE * pbuffer,int fd,int plane_offset,unsigned long inputformat,bool interlaced)1385 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset,
1386         unsigned long inputformat, bool interlaced) {
1387     int status = 0;
1388     if (venc_handle->is_secure_session()) {
1389         DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
1390         return -1;
1391     }
1392 
1393     sync_start_read(fd);
1394     if (!m_debug.infile) {
1395         int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
1396                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
1397         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
1398              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
1399                                 m_debug.infile_name, size);
1400         }
1401         m_debug.infile = fopen (m_debug.infile_name, "ab");
1402         if (!m_debug.infile) {
1403             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
1404             m_debug.infile_name[0] = '\0';
1405             status = -1;
1406             goto bailout;
1407         }
1408     }
1409 
1410     if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
1411         unsigned long stride, scanlines;
1412         unsigned long color_format;
1413         unsigned long i, msize;
1414         unsigned char *pvirt = NULL, *ptemp = NULL;
1415         unsigned char *temp = (unsigned char *)pbuffer->pBuffer;
1416 
1417         color_format = get_media_colorformat(inputformat);
1418 
1419         msize = VENUS_BUFFER_SIZE_USED(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,interlaced);
1420         const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
1421 
1422         if (metadatamode == 1) {
1423             pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
1424             if (pvirt == MAP_FAILED) {
1425                 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
1426                 status = -1;
1427                 goto bailout;
1428             }
1429             ptemp = pvirt;
1430         } else {
1431             ptemp = temp;
1432         }
1433 
1434         if (color_format == COLOR_FMT_NV12) {
1435             stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
1436             scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
1437 
1438             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1439                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1440                 ptemp += stride;
1441             }
1442             if (metadatamode == 1) {
1443                 ptemp = pvirt + (stride * scanlines);
1444             } else {
1445                 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
1446             }
1447             for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
1448                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
1449                 ptemp += stride;
1450             }
1451         } else if (color_format == COLOR_FMT_NV12_512) {
1452             stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
1453             scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
1454 
1455             for (i = 0; i < scanlines; i++) {
1456                 fwrite(ptemp, stride, 1, m_debug.infile);
1457                 ptemp += stride;
1458             }
1459             if (metadatamode == 1) {
1460                 ptemp = pvirt + (stride * scanlines);
1461             } else {
1462                 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
1463             }
1464             for (i = 0; i < scanlines/2; i++) {
1465                 fwrite(ptemp, stride, 1, m_debug.infile);
1466                 ptemp += stride;
1467             }
1468         } else if (color_format == COLOR_FMT_RGBA8888) {
1469             stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width);
1470             scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height);
1471 
1472             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1473                 fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile);
1474                 ptemp += stride;
1475             }
1476         } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_NV12_BPP10_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) {
1477             fwrite(ptemp, msize, 1, m_debug.infile);
1478         } else if(color_format == COLOR_FMT_P010) {
1479             stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
1480             scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
1481 
1482             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
1483                 fwrite(ptemp, m_sVenc_cfg.input_width*2, 1, m_debug.infile);
1484                 ptemp += stride;
1485             }
1486             if (metadatamode == 1) {
1487                 ptemp = pvirt + (stride * scanlines);
1488             } else {
1489                 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
1490             }
1491             for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
1492                 fwrite(ptemp, m_sVenc_cfg.input_width*2, 1, m_debug.infile);
1493                 ptemp += stride;
1494             }
1495         }
1496 
1497         if (metadatamode == 1 && pvirt) {
1498             munmap(pvirt, msize);
1499         }
1500     }
1501 bailout:
1502     sync_end_read(fd);
1503     return status;
1504 }
1505 
venc_open(OMX_U32 codec)1506 bool venc_dev::venc_open(OMX_U32 codec)
1507 {
1508     int r, minqp = 0, maxqp = 127;
1509     unsigned int alignment = 0,buffer_size = 0, temp =0;
1510     struct v4l2_control control;
1511     OMX_STRING device_name = (OMX_STRING)"/dev/video33";
1512     char property_value[PROPERTY_VALUE_MAX] = {0};
1513     FILE *soc_file = NULL;
1514     char buffer[10];
1515 
1516     m_nDriver_fd = open (device_name, O_RDWR);
1517     if ((int)m_nDriver_fd < 0) {
1518         DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
1519         return false;
1520     }
1521     m_poll_efd = eventfd(0, 0);
1522     if (m_poll_efd < 0) {
1523         DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno));
1524         return false;
1525     }
1526     DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
1527 
1528     // set the basic configuration of the video encoder driver
1529     m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
1530     m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
1531     m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
1532     m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
1533     m_sVenc_cfg.fps_num = 30;
1534     m_sVenc_cfg.fps_den = 1;
1535     m_sVenc_cfg.targetbitrate = 64000;
1536     m_sVenc_cfg.inputformat= V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1537     m_rotation.rotation = 0;
1538     m_codec = codec;
1539     downscalar_enabled = OMX_FALSE;
1540 
1541     if (codec == OMX_VIDEO_CodingAVC) {
1542         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
1543         codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1544         profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1545         idrperiod.idrperiod = 1;
1546         minqp = 0;
1547         maxqp = 51;
1548     } else if (codec == OMX_VIDEO_CodingVP8) {
1549         m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
1550         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
1551         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
1552         minqp = 0;
1553         maxqp = 127;
1554     } else if (codec == OMX_VIDEO_CodingHEVC || codec == OMX_VIDEO_CodingImageHEIC) {
1555         m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
1556         idrperiod.idrperiod = 1;
1557         minqp = 0;
1558         maxqp = 51;
1559         if (codec == OMX_VIDEO_CodingImageHEIC) {
1560             m_sVenc_cfg.input_width = DEFAULT_TILE_DIMENSION;
1561             m_sVenc_cfg.input_height= DEFAULT_TILE_DIMENSION;
1562             m_sVenc_cfg.dvs_width = DEFAULT_TILE_DIMENSION;
1563             m_sVenc_cfg.dvs_height = DEFAULT_TILE_DIMENSION;
1564             codec_profile.profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;
1565         } else
1566             codec_profile.profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
1567         profile_level.level = V4L2_MPEG_VIDEO_HEVC_LEVEL_1;
1568     }
1569 
1570     session_ipb_qp_values.min_qp_packed = minqp | (minqp << 8) | (minqp << 16);
1571     session_ipb_qp_values.max_qp_packed = maxqp | (maxqp << 8) | (maxqp << 16);
1572 
1573     int ret;
1574     ret = subscribe_to_events(m_nDriver_fd);
1575 
1576     if (ret) {
1577         DEBUG_PRINT_ERROR("Subscribe Event Failed");
1578         return false;
1579     }
1580 
1581     struct v4l2_fmtdesc fdesc;
1582     struct v4l2_format fmt;
1583     struct v4l2_requestbuffers bufreq;
1584     struct v4l2_capability cap;
1585 
1586     ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
1587 
1588     if (ret) {
1589         DEBUG_PRINT_ERROR("Failed to query capabilities");
1590     } else {
1591         DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1592                 " version = %d, capabilities = %x", cap.driver, cap.card,
1593                 cap.bus_info, cap.version, cap.capabilities);
1594     }
1595 
1596     ret=0;
1597     fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1598     fdesc.index=0;
1599 
1600     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1601         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1602                 fdesc.pixelformat, fdesc.flags);
1603         fdesc.index++;
1604     }
1605 
1606     fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1607     fdesc.index=0;
1608 
1609     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1610         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
1611                 fdesc.pixelformat, fdesc.flags);
1612         fdesc.index++;
1613     }
1614 
1615     if(venc_handle->is_secure_session()) {
1616         control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1617         control.value = 1;
1618         DEBUG_PRINT_HIGH("ioctl: open secure device");
1619         ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
1620         if (ret) {
1621             DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
1622             return false;
1623         }
1624     }
1625 
1626     if (venc_handle->is_secure_session()) {
1627         m_sOutput_buff_property.alignment = SZ_1M;
1628         m_sInput_buff_property.alignment  = SZ_1M;
1629     } else {
1630         m_sOutput_buff_property.alignment = SZ_4K;
1631         m_sInput_buff_property.alignment  = SZ_4K;
1632     }
1633 
1634     if (m_codec == OMX_VIDEO_CodingImageHEIC) {
1635         if (!venc_set_grid_enable()) {
1636             DEBUG_PRINT_ERROR("Failed to enable grid");
1637             return false;
1638         }
1639     }
1640 
1641     memset(&fmt, 0, sizeof(fmt));
1642     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1643     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1644     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1645     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1646 
1647     /*TODO: Return values not handled properly in this function anywhere.
1648      * Need to handle those.*/
1649     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1650 
1651     if (ret) {
1652         DEBUG_PRINT_ERROR("Failed to set format on capture port");
1653         return false;
1654     }
1655 
1656     m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1657 
1658     memset(&fmt, 0, sizeof(fmt));
1659     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1660     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1661     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1662     fmt.fmt.pix_mp.pixelformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
1663     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1664 
1665     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1666     m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1667 
1668     bufreq.memory = V4L2_MEMORY_USERPTR;
1669     bufreq.count = 2;
1670 
1671     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1672     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1673     m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
1674 
1675     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1676     bufreq.count = 2;
1677     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
1678     m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
1679 
1680     resume_in_stopped = 0;
1681     metadatamode = 0;
1682 
1683     struct v4l2_frmsizeenum frmsize;
1684 
1685     //Get the hardware capabilities
1686     memset((void *)&frmsize,0,sizeof(frmsize));
1687     frmsize.index = 0;
1688     frmsize.pixel_format = m_sVenc_cfg.codectype;
1689     ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1690 
1691     if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1692         DEBUG_PRINT_ERROR("Failed to get framesizes");
1693         return false;
1694     }
1695 
1696     if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1697         capability.min_width = frmsize.stepwise.min_width;
1698         capability.max_width = frmsize.stepwise.max_width;
1699         capability.min_height = frmsize.stepwise.min_height;
1700         capability.max_height = frmsize.stepwise.max_height;
1701     }
1702 
1703     //Initialize non-default parameters
1704     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
1705         control.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
1706         control.value = 0x7fffffff;
1707         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1708             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
1709     }
1710 
1711     //Disable auto blur by default
1712     if (is_auto_blur_disabled) {
1713         control.id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS;
1714         control.value = 0x2;
1715         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
1716            DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS\n");
1717     }
1718 
1719 
1720     /* Enable Low power mode by default for better power */
1721 
1722     input_extradata_info.port_index = OUTPUT_PORT;
1723     output_extradata_info.port_index = CAPTURE_PORT;
1724 
1725     return true;
1726 }
1727 
unsubscribe_to_events(int fd)1728 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
1729 {
1730     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1731     struct v4l2_event_subscription sub;
1732     int array_sz = sizeof(event_type)/sizeof(int);
1733     int i,rc;
1734 
1735     if (fd < 0) {
1736        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1737         return OMX_ErrorBadParameter;
1738     }
1739 
1740     for (i = 0; i < array_sz; ++i) {
1741         memset(&sub, 0, sizeof(sub));
1742         sub.type = event_type[i];
1743         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1744 
1745         if (rc) {
1746            DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1747             break;
1748         }
1749     }
1750 
1751     return eRet;
1752 }
1753 
venc_close()1754 void venc_dev::venc_close()
1755 {
1756     DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
1757 
1758     if ((int)m_nDriver_fd >= 0) {
1759         DEBUG_PRINT_HIGH("venc_close E");
1760 
1761         if(eventfd_write(m_poll_efd, 1)) {
1762             DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1763             async_thread_force_stop = true;
1764         }
1765 
1766         if (async_thread_created)
1767             pthread_join(m_tid,NULL);
1768 
1769         if (venc_handle->msg_thread_created) {
1770             venc_handle->msg_thread_created = false;
1771             venc_handle->msg_thread_stop = true;
1772             post_message(venc_handle, omx_video::OMX_COMPONENT_CLOSE_MSG);
1773             DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
1774             pthread_join(venc_handle->msg_thread_id, NULL);
1775         }
1776         DEBUG_PRINT_HIGH("venc_close X");
1777         unsubscribe_to_events(m_nDriver_fd);
1778         close(m_poll_efd);
1779         close(m_nDriver_fd);
1780         m_nDriver_fd = -1;
1781     }
1782 
1783     if (m_debug.infile) {
1784         fclose(m_debug.infile);
1785         m_debug.infile = NULL;
1786     }
1787 
1788     if (m_debug.outfile) {
1789         fclose(m_debug.outfile);
1790         m_debug.outfile = NULL;
1791     }
1792 
1793     if (m_debug.extradatafile) {
1794         fclose(m_debug.extradatafile);
1795         m_debug.extradatafile = NULL;
1796     }
1797 
1798     if (m_debug.cvpfile) {
1799         fclose(m_debug.cvpfile);
1800         m_debug.cvpfile = NULL;
1801     }
1802 }
1803 
venc_set_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1804 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
1805         OMX_U32 *actual_buff_count,
1806         OMX_U32 *buff_size,
1807         OMX_U32 port)
1808 {
1809     (void)min_buff_count, (void)buff_size;
1810     unsigned long temp_count = 0;
1811 
1812     if (port == 0) {
1813         if (*actual_buff_count > m_sInput_buff_property.mincount) {
1814             temp_count = m_sInput_buff_property.actualcount;
1815             m_sInput_buff_property.actualcount = *actual_buff_count;
1816             DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
1817         }
1818     } else {
1819         if (*actual_buff_count > m_sOutput_buff_property.mincount) {
1820             temp_count = m_sOutput_buff_property.actualcount;
1821             m_sOutput_buff_property.actualcount = *actual_buff_count;
1822             DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
1823         }
1824     }
1825 
1826     return true;
1827 
1828 }
1829 
venc_loaded_start()1830 bool venc_dev::venc_loaded_start()
1831 {
1832     return true;
1833 }
1834 
venc_loaded_stop()1835 bool venc_dev::venc_loaded_stop()
1836 {
1837     return true;
1838 }
1839 
venc_loaded_start_done()1840 bool venc_dev::venc_loaded_start_done()
1841 {
1842     return true;
1843 }
1844 
venc_loaded_stop_done()1845 bool venc_dev::venc_loaded_stop_done()
1846 {
1847     return true;
1848 }
1849 
venc_get_seq_hdr(void * buffer,unsigned buffer_size,unsigned * header_len)1850 bool venc_dev::venc_get_seq_hdr(void *buffer,
1851         unsigned buffer_size, unsigned *header_len)
1852 {
1853     (void) buffer, (void) buffer_size, (void) header_len;
1854     return true;
1855 }
1856 
venc_get_dimensions(OMX_U32 portIndex,OMX_U32 * w,OMX_U32 * h)1857 bool venc_dev::venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h) {
1858     struct v4l2_format fmt;
1859     memset(&fmt, 0, sizeof(fmt));
1860     fmt.type = portIndex == PORT_INDEX_OUT ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
1861             V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1862 
1863     if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
1864         DEBUG_PRINT_ERROR("Failed to get format on %s port",
1865                 portIndex == PORT_INDEX_OUT ? "capture" : "output");
1866         return false;
1867     }
1868     *w = fmt.fmt.pix_mp.width;
1869     *h = fmt.fmt.pix_mp.height;
1870     return true;
1871 }
1872 
venc_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)1873 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
1874         OMX_U32 *actual_buff_count,
1875         OMX_U32 *buff_size,
1876         OMX_U32 port)
1877 {
1878     struct v4l2_format fmt;
1879     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
1880     int ret;
1881     int extra_idx = 0;
1882     struct v4l2_control control;
1883     unsigned int minCount = 0;
1884 
1885     memset(&control, 0, sizeof(control));
1886     memset(&fmt, 0, sizeof(fmt));
1887 
1888     if (port == 0) {
1889         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1890         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1891         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1892         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1893         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
1894         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1895         if (ret) {
1896             DEBUG_PRINT_ERROR("set format failed, type %d, wxh %dx%d, format %#x, colorspace %d\n",
1897                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
1898                 fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.colorspace);
1899             return false;
1900         }
1901         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1902 
1903         control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
1904         ret = ioctl(m_nDriver_fd,  VIDIOC_G_CTRL, &control);
1905         if (ret || (unsigned int)control.value > MAX_V4L2_BUFS) {
1906             DEBUG_PRINT_ERROR("Driver returned invalid data, port = %d ret = %d Count = %d",
1907                 port, ret, (unsigned int)control.value);
1908             return false;
1909         }
1910 
1911         // Request MAX_V4L2_BUFS from V4L2 in batch mode.
1912         // Keep the original count for the client
1913         if (metadatamode && mBatchSize) {
1914             minCount = MAX_V4L2_BUFS;
1915             DEBUG_PRINT_LOW("Set buffer count = %d as metadata mode and batchmode enabled", minCount);
1916         }
1917 
1918         minCount = MAX((unsigned int)control.value, minCount);
1919         m_sInput_buff_property.mincount = minCount;
1920         m_sInput_buff_property.actualcount = m_sInput_buff_property.mincount;
1921 
1922         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1923         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
1924         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
1925         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
1926         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1927         if (ret) {
1928             DEBUG_PRINT_ERROR("get format failed, type %d, wxh %dx%d, format %#x\n",
1929                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
1930                 fmt.fmt.pix_mp.pixelformat);
1931             return false;
1932         }
1933         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1934 
1935         *min_buff_count = m_sInput_buff_property.mincount;
1936         *actual_buff_count = m_sInput_buff_property.actualcount;
1937 #ifdef USE_ION
1938         // For ION memory allocations of the allocated buffer size
1939         // must be 4k aligned, hence aligning the input buffer
1940         // size to 4k.
1941         m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
1942 #endif
1943         *buff_size = m_sInput_buff_property.datasize;
1944         num_input_planes = fmt.fmt.pix_mp.num_planes;
1945         extra_idx = EXTRADATA_IDX(num_input_planes);
1946 
1947         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
1948             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
1949         } else if (extra_idx >= VIDEO_MAX_PLANES) {
1950             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
1951             return false;
1952         }
1953         input_extradata_info.buffer_size =  ALIGN(extra_data_size, SZ_4K);
1954         input_extradata_info.count = m_sInput_buff_property.actualcount;
1955         venc_handle->m_client_in_extradata_info.set_extradata_info(input_extradata_info.buffer_size,m_sInput_buff_property.actualcount);
1956     } else {
1957         unsigned int extra_idx = 0;
1958         memset(&fmt, 0, sizeof(fmt));
1959         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1960         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1961         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1962         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1963 
1964         ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
1965         if (ret) {
1966             DEBUG_PRINT_ERROR("set format failed, type %d, wxh %dx%d, format %#x\n",
1967                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
1968                 fmt.fmt.pix_mp.pixelformat);
1969             return false;
1970         }
1971 
1972         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1973         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1974         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
1975         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
1976         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
1977 
1978         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
1979         if (ret) {
1980             DEBUG_PRINT_ERROR("get format failed, type %d, wxh %dx%d, format %#x\n",
1981                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
1982                 fmt.fmt.pix_mp.pixelformat);
1983             return false;
1984         }
1985         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1986 
1987         control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
1988 
1989         ret = ioctl(m_nDriver_fd,  VIDIOC_G_CTRL, &control);
1990         if (ret || (unsigned int)control.value > MAX_V4L2_BUFS) {
1991             DEBUG_PRINT_ERROR("Driver returned invalid data port = %d ret = %d Count = %d",
1992                 port, ret, (unsigned int)control.value);
1993             return false;
1994         }
1995         minCount = control.value;
1996 
1997         if (mBatchSize) {
1998             // If we're in batch mode, we'd like to end up in a situation where
1999             // driver is able to own mBatchSize buffers and we'd also own atleast
2000             // mBatchSize buffers
2001             minCount = MAX((unsigned int)control.value, mBatchSize) + mBatchSize;
2002             DEBUG_PRINT_LOW("set min count %d as mBatchSize %d", minCount, mBatchSize);
2003         }
2004 
2005         m_sOutput_buff_property.mincount = minCount;
2006         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount;
2007 
2008         *min_buff_count = m_sOutput_buff_property.mincount;
2009         *actual_buff_count = m_sOutput_buff_property.actualcount;
2010         *buff_size = m_sOutput_buff_property.datasize;
2011         num_output_planes = fmt.fmt.pix_mp.num_planes;
2012         extra_idx = EXTRADATA_IDX(num_output_planes);
2013 
2014         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
2015             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
2016         } else if (extra_idx >= VIDEO_MAX_PLANES) {
2017             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
2018             return false;
2019         }
2020 
2021         output_extradata_info.buffer_size = ALIGN(extra_data_size, SZ_4K);
2022         output_extradata_info.count = m_sOutput_buff_property.actualcount;
2023         venc_handle->m_client_out_extradata_info.set_extradata_info(output_extradata_info.buffer_size,output_extradata_info.count);
2024     }
2025 
2026     DEBUG_PRINT_HIGH("venc_get_buf_req: port %d, wxh %dx%d, format %#x, driver min count %d, "
2027         "updated min count %d, act count %d, size %d, num planes %d",
2028         port, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.pixelformat,
2029         control.value, *min_buff_count, *actual_buff_count, *buff_size, fmt.fmt.pix_mp.num_planes);
2030 
2031     return true;
2032 }
2033 
venc_handle_empty_eos_buffer(void)2034 bool venc_dev::venc_handle_empty_eos_buffer( void)
2035 {
2036     struct v4l2_encoder_cmd enc;
2037     int rc = 0;
2038 
2039     if (!streaming[OUTPUT_PORT]) {
2040         enum v4l2_buf_type buf_type;
2041         struct v4l2_control control;
2042         int ret = 0;
2043 
2044         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2045 
2046         DEBUG_PRINT_HIGH("Calling streamon before issuing stop command for EOS");
2047         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
2048         if (ret) {
2049             DEBUG_PRINT_ERROR("Failed to call streamon");
2050             if (errno == EBUSY) {
2051                 hw_overload = true;
2052             }
2053             return false;
2054         } else {
2055             streaming[OUTPUT_PORT] = true;
2056         }
2057     }
2058 
2059     memset(&enc, 0, sizeof(enc));
2060     enc.cmd = V4L2_ENC_CMD_STOP;
2061     DEBUG_PRINT_LOW("Sending : Encoder STOP comamnd");
2062     rc = ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
2063     if (rc) {
2064         DEBUG_PRINT_ERROR("Failed : Encoder STOP comamnd");
2065         return false;
2066     }
2067     return true;
2068 }
2069 
venc_stop(void)2070 unsigned venc_dev::venc_stop( void)
2071 {
2072     struct venc_msg venc_msg;
2073     struct v4l2_requestbuffers bufreq;
2074     int rc = 0, ret = 0;
2075 
2076     if (!stopped) {
2077         enum v4l2_buf_type cap_type;
2078 
2079         if (streaming[OUTPUT_PORT]) {
2080             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2081             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2082 
2083             if (rc) {
2084                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2085                         cap_type, rc);
2086             } else
2087                 streaming[OUTPUT_PORT] = false;
2088 
2089             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
2090             bufreq.memory = V4L2_MEMORY_USERPTR;
2091             bufreq.count = 0;
2092             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2093             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2094 
2095             if (ret) {
2096                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
2097                 return false;
2098             }
2099         }
2100 
2101         if (!rc && streaming[CAPTURE_PORT]) {
2102             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2103             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
2104 
2105             if (rc) {
2106                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
2107                         cap_type, rc);
2108             } else
2109                 streaming[CAPTURE_PORT] = false;
2110 
2111             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
2112             bufreq.memory = V4L2_MEMORY_USERPTR;
2113             bufreq.count = 0;
2114             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2115             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
2116 
2117             if (ret) {
2118                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
2119                 return false;
2120             }
2121         }
2122 
2123         if (!rc && !ret) {
2124             venc_stop_done();
2125             stopped = 1;
2126             /*set flag to re-configure when started again*/
2127             resume_in_stopped = 1;
2128         }
2129     }
2130 
2131     return rc;
2132 }
2133 
is_streamon_done(OMX_U32 port)2134 bool venc_dev::is_streamon_done(OMX_U32 port)
2135 {
2136     return streaming[port];
2137 }
2138 
venc_pause(void)2139 unsigned venc_dev::venc_pause(void)
2140 {
2141     pthread_mutex_lock(&pause_resume_mlock);
2142     paused = true;
2143     pthread_mutex_unlock(&pause_resume_mlock);
2144     return 0;
2145 }
2146 
venc_resume(void)2147 unsigned venc_dev::venc_resume(void)
2148 {
2149     pthread_mutex_lock(&pause_resume_mlock);
2150     paused = false;
2151     pthread_mutex_unlock(&pause_resume_mlock);
2152 
2153     return pthread_cond_signal(&pause_resume_cond);
2154 }
2155 
venc_start_done(void)2156 unsigned venc_dev::venc_start_done(void)
2157 {
2158     struct venc_msg venc_msg;
2159     venc_msg.msgcode = VEN_MSG_START;
2160     venc_msg.statuscode = VEN_S_SUCCESS;
2161     venc_handle->async_message_process(venc_handle,&venc_msg);
2162     return 0;
2163 }
2164 
venc_stop_done(void)2165 unsigned venc_dev::venc_stop_done(void)
2166 {
2167     struct venc_msg venc_msg;
2168     free_extradata_all();
2169     venc_msg.msgcode=VEN_MSG_STOP;
2170     venc_msg.statuscode=VEN_S_SUCCESS;
2171     venc_handle->async_message_process(venc_handle,&venc_msg);
2172     return 0;
2173 }
2174 
venc_set_message_thread_id(pthread_t tid)2175 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
2176 {
2177     async_thread_created = true;
2178     m_tid=tid;
2179     return 0;
2180 }
2181 
venc_set_extradata_hdr10metadata(OMX_U32 omx_profile)2182 bool venc_dev::venc_set_extradata_hdr10metadata(OMX_U32 omx_profile)
2183 {
2184     /* HDR10 Metadata is enabled by default for HEVC Main10PLUS profile. */
2185     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC &&
2186         omx_profile == OMX_VIDEO_HEVCProfileMain10HDR10Plus) {
2187         DEBUG_PRINT_HIGH("venc_set_extradata:: HDR10PLUS_METADATA");
2188         struct v4l2_control control;
2189         control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
2190         control.value = EXTRADATA_ENC_INPUT_HDR10PLUS;
2191 
2192         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2193             DEBUG_PRINT_ERROR("ERROR: Set extradata HDR10PLUS_METADATA failed %d", errno);
2194             return false;
2195         }
2196 
2197         m_hdr10meta_enabled = true;
2198 
2199         //Get upated buffer requirement as enable extradata leads to two buffer planes
2200         venc_get_buf_req (&venc_handle->m_sInPortDef.nBufferCountMin,
2201                           &venc_handle->m_sInPortDef.nBufferCountActual,
2202                           &venc_handle->m_sInPortDef.nBufferSize,
2203                           venc_handle->m_sInPortDef.nPortIndex);
2204     } else {
2205         m_hdr10meta_enabled = false;
2206     }
2207 
2208     return true;
2209 }
2210 
venc_start(void)2211 unsigned venc_dev::venc_start(void)
2212 {
2213     enum v4l2_buf_type buf_type;
2214     int ret, r;
2215     struct v4l2_control control;
2216 
2217     memset(&control, 0, sizeof(control));
2218 
2219     venc_config_print();
2220 
2221     /* set buffercount before start */
2222     venc_reconfig_reqbufs();
2223     resume_in_stopped = 0;
2224 
2225     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2226     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2227     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
2228 
2229     if (ret)
2230         return 1;
2231 
2232     streaming[CAPTURE_PORT] = true;
2233 
2234     stopped = 0;
2235     return 0;
2236 }
2237 
hiermode_string(int val)2238 inline const char* hiermode_string(int val)
2239 {
2240     switch(val)
2241     {
2242     case HIER_NONE:
2243         return "No Hier";
2244     case HIER_P:
2245         return "Hier-P";
2246     case HIER_B:
2247         return "Hier-B";
2248     default:
2249         return "No hier";
2250     }
2251 }
2252 
bitrate_type_string(int val)2253 inline const char* bitrate_type_string(int val)
2254 {
2255     switch(val)
2256     {
2257     case V4L2_MPEG_MSM_VIDC_DISABLE:
2258         return "CUMULATIVE";
2259     case V4L2_MPEG_MSM_VIDC_ENABLE:
2260         return "LAYER WISE";
2261     default:
2262         return "Unknown Bitrate Type";
2263     }
2264 }
2265 
codec_as_string(unsigned long codec)2266 static const char *codec_as_string(unsigned long codec) {
2267     switch (codec) {
2268     case V4L2_PIX_FMT_H264:
2269         return "H264";
2270     case V4L2_PIX_FMT_HEVC:
2271         return "HEVC";
2272     case V4L2_PIX_FMT_VP8:
2273         return "VP8";
2274     default:
2275         return "UNKOWN";
2276     }
2277 }
2278 
venc_config_print()2279 void venc_dev::venc_config_print()
2280 {
2281 
2282     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
2283             codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
2284 
2285     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
2286             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
2287             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2288 
2289     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
2290             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
2291             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
2292 
2293     DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
2294             color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
2295 
2296     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
2297             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
2298 
2299     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld enableqp : %ld",
2300             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp, session_qp.enableqp);
2301 
2302     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
2303                      session_ipb_qp_values.min_qp_packed, session_ipb_qp_values.max_qp_packed);
2304 
2305     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
2306             voptimecfg.voptime_resolution, multislice.mslice_mode,
2307             multislice.mslice_size);
2308 
2309     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
2310             entropy.longentropysel, entropy.cabacmodel);
2311 
2312     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
2313             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
2314             dbkfilter.slicebeta_offset);
2315 
2316     DEBUG_PRINT_HIGH("ENC_CONFIG: HEC: %ld, IDR Period: %ld",
2317             hec.header_extension, idrperiod.idrperiod);
2318 
2319     if (temporal_layers_config.nPLayers) {
2320         DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
2321                 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
2322                 intra_period.num_pframes + intra_period.num_bframes + 1);
2323     }
2324 
2325     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
2326 
2327     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
2328 
2329     DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %s", sess_priority.priority ? "NonRealTime" : "RealTime");
2330 
2331     DEBUG_PRINT_HIGH("ENC_CONFIG: ROI : %u", m_roi_enabled);
2332 
2333     DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
2334 }
2335 
venc_reconfig_reqbufs()2336 bool venc_dev::venc_reconfig_reqbufs()
2337 {
2338     struct v4l2_requestbuffers bufreq;
2339 
2340     DEBUG_PRINT_HIGH("venc_reconfig_reqbufs: output_mplane %lu, capture_mplane %lu",
2341         m_sInput_buff_property.actualcount, m_sOutput_buff_property.actualcount);
2342 
2343     bufreq.memory = V4L2_MEMORY_USERPTR;
2344     bufreq.count = m_sInput_buff_property.actualcount;
2345     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2346     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2347         DEBUG_PRINT_ERROR("VIDIOC_REQBUFS: OUTPUT_MPLANE (count %d) failed", bufreq.count);
2348         return false;
2349     }
2350 
2351     bufreq.memory = V4L2_MEMORY_USERPTR;
2352     bufreq.count = m_sOutput_buff_property.actualcount;
2353     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2354     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2355         DEBUG_PRINT_ERROR("VIDIOC_REQBUFS: CAPTURE_MPLANE (count %d) failed", bufreq.count);
2356         return false;
2357     }
2358     return true;
2359 }
2360 
venc_flush(unsigned port)2361 unsigned venc_dev::venc_flush( unsigned port)
2362 {
2363     struct v4l2_encoder_cmd enc;
2364     DEBUG_PRINT_LOW("in %s", __func__);
2365 
2366     enc.cmd = V4L2_CMD_FLUSH;
2367     enc.flags = V4L2_CMD_FLUSH_OUTPUT | V4L2_CMD_FLUSH_CAPTURE;
2368 
2369     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
2370         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
2371         return -1;
2372     }
2373 
2374     return 0;
2375 }
2376 
2377 //allocating I/P memory from pmem and register with the device
allocate_extradata(unsigned port)2378 bool venc_dev::allocate_extradata(unsigned port)
2379 {
2380     int rc = 0;
2381     unsigned int extra_idx = 0;
2382 
2383     // PORT_INDEX_IN = 0
2384     // PORT_INDEX_OUT = 1
2385     struct port_info_s {
2386         int num_planes;
2387         struct extradata_buffer_info *extradata_info;
2388         int flag;
2389     }port_info[2] = {
2390         {
2391             .num_planes = num_input_planes,
2392             .extradata_info = &input_extradata_info,
2393             .flag = 0
2394         },
2395         {
2396             .num_planes = num_output_planes,
2397             .extradata_info = &output_extradata_info,
2398             .flag = 0
2399         }
2400     };
2401 
2402     if (port != PORT_INDEX_IN && port != PORT_INDEX_OUT) {
2403         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
2404         return false;
2405     }
2406 
2407     extra_idx = EXTRADATA_IDX(port_info[port].num_planes);
2408     if ((port_info[port].num_planes > 1) && (extra_idx)) {
2409         rc = allocate_extradata(port_info[port].extradata_info,
2410                                 port_info[port].flag);
2411         if (rc) {
2412             DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc);
2413             return false;
2414         }
2415     }
2416 
2417     return true;
2418 }
2419 
venc_free_buf(void * buf_addr,unsigned port)2420 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
2421 {
2422     struct pmem *pmem_tmp;
2423     struct venc_bufferpayload dev_buffer;
2424 
2425     memset(&dev_buffer, 0, sizeof(dev_buffer));
2426     pmem_tmp = (struct pmem *)buf_addr;
2427 
2428     if (port == PORT_INDEX_IN) {
2429         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2430         dev_buffer.fd  = pmem_tmp->fd;
2431         dev_buffer.maped_size = pmem_tmp->size;
2432         dev_buffer.sz = pmem_tmp->size;
2433         dev_buffer.offset = pmem_tmp->offset;
2434         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2435                 dev_buffer.pbuffer, \
2436                 dev_buffer.fd, \
2437                 dev_buffer.offset, \
2438                 dev_buffer.maped_size);
2439 
2440     } else if (port == PORT_INDEX_OUT) {
2441         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
2442         dev_buffer.fd  = pmem_tmp->fd;
2443         dev_buffer.sz = pmem_tmp->size;
2444         dev_buffer.maped_size = pmem_tmp->size;
2445         dev_buffer.offset = pmem_tmp->offset;
2446 
2447         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
2448                 dev_buffer.pbuffer, \
2449                 dev_buffer.fd, \
2450                 dev_buffer.offset, \
2451                 dev_buffer.maped_size);
2452     } else {
2453         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
2454         return false;
2455     }
2456 
2457     return true;
2458 }
2459 
venc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2460 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
2461         OMX_U32 width, OMX_U32 height)
2462 {
2463     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
2464             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
2465             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
2466             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
2467             src_chroma_offset = width * height;
2468 
2469     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
2470         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
2471         //Do chroma first, so that we can convert it in-place
2472         src_buf += width * height;
2473         dst_buf += y_stride * y_scanlines;
2474         for (int line = height / 2 - 1; line >= 0; --line) {
2475             /* Align the length to 16 for better memove performance. */
2476             memmove(dst_buf + line * uv_stride,
2477                     src_buf + line * width,
2478                     ALIGN(width, 16));
2479         }
2480 
2481         dst_buf = src_buf = buffer->pBuffer;
2482         //Copy the Y next
2483         for (int line = height - 1; line > 0; --line) {
2484             /* Align the length to 16 for better memove performance. */
2485             memmove(dst_buf + line * y_stride,
2486                     src_buf + line * width,
2487                     ALIGN(width, 16));
2488         }
2489         /* Inform driver to do cache flush on total buffer */
2490         buffer->nFilledLen = buffer->nAllocLen;
2491     } else {
2492         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
2493                 Insufficient bufferLen=%u v/s Required=%u",
2494                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
2495                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
2496         return false;
2497     }
2498 
2499     return true;
2500 }
2501 
venc_get_vui_timing_info(OMX_U32 * enabled)2502 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
2503 {
2504     if (!enabled) {
2505         DEBUG_PRINT_ERROR("Null pointer error");
2506         return false;
2507     } else {
2508         *enabled = vui_timing_info.enabled;
2509         return true;
2510     }
2511 }
2512 
venc_get_peak_bitrate(OMX_U32 * peakbitrate)2513 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
2514 {
2515     if (!peakbitrate) {
2516         DEBUG_PRINT_ERROR("Null pointer error");
2517         return false;
2518     } else {
2519         *peakbitrate = peak_bitrate.peakbitrate;
2520         return true;
2521     }
2522 }
2523 
venc_get_batch_size(OMX_U32 * size)2524 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
2525 {
2526     if (!size) {
2527         DEBUG_PRINT_ERROR("Null pointer error");
2528         return false;
2529     } else {
2530         *size = mBatchSize;
2531         return true;
2532     }
2533 }
2534 
venc_get_buffer_mode()2535 bool venc_dev::venc_get_buffer_mode()
2536 {
2537     return metadatamode;
2538 }
2539 
venc_is_avtimer_needed()2540 bool venc_dev::venc_is_avtimer_needed()
2541 {
2542     return mUseAVTimerTimestamps;
2543 }
2544 
venc_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2545 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
2546 {
2547     struct pmem *temp_buffer;
2548     struct v4l2_buffer buf;
2549     struct v4l2_requestbuffers bufreq;
2550     struct v4l2_plane plane[VIDEO_MAX_PLANES];
2551     int rc = 0, extra_idx, c2d_enabled = 0;
2552     bool interlace_flag = false;
2553     struct OMX_BUFFERHEADERTYPE *bufhdr;
2554     LEGACY_CAM_METADATA_TYPE * meta_buf = NULL;
2555     temp_buffer = (struct pmem *)buffer;
2556 
2557     memset (&buf, 0, sizeof(buf));
2558     memset (&plane, 0, sizeof(plane));
2559 
2560     if (buffer == NULL) {
2561         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
2562         return false;
2563     }
2564 
2565     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2566     bufreq.memory = V4L2_MEMORY_USERPTR;
2567     bufreq.count = m_sInput_buff_property.actualcount;
2568     bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2569 
2570     if (pmem_data_buf) {
2571         DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
2572         plane[0].m.userptr = (unsigned long)pmem_data_buf;
2573         plane[0].data_offset = bufhdr->nOffset;
2574         plane[0].length = bufhdr->nAllocLen;
2575         plane[0].bytesused = bufhdr->nFilledLen;
2576     } else {
2577         // --------------------------------------------------------------------------------------
2578         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
2579         // ---------------------------------------------------------------------------------------
2580         // Camera-2              1            CameraSource   0              meta-handle
2581         // Camera-3              1            GrallocSource  0              gralloc-private-handle
2582         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
2583         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
2584         // ---------------------------------------------------------------------------------------
2585         if (metadatamode) {
2586             plane[0].m.userptr = index;
2587             meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
2588 
2589             if (!meta_buf) {
2590                 if (!bufhdr->nFilledLen) {
2591                     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) {
2592                         DEBUG_PRINT_ERROR("venc_empty_buf: Zero length EOS buffers are not valid");
2593                         DEBUG_PRINT_ERROR("Use this function instead : venc_handle_empty_eos_buffer");
2594                         return false;
2595                     }
2596                     DEBUG_PRINT_ERROR("venc_empty_buf: Zero length buffers are not valid");
2597                     return false;
2598                 }
2599             } else if (!color_format) { // Metadata mode
2600 
2601                 if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) {
2602                     native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
2603                     if (!hnd) {
2604                         DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
2605                         return false;
2606                     }
2607                     int usage = 0;
2608                     usage = MetaBufferUtil::getIntAt(hnd, 0, MetaBufferUtil::INT_USAGE);
2609                     usage = usage > 0 ? usage : 0;
2610 
2611                     if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
2612                         m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
2613 
2614                         unsigned int is_csc_enabled = 0;
2615                         struct v4l2_format fmt;
2616                         OMX_COLOR_FORMATTYPE color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2617 
2618                         color_format = (OMX_COLOR_FORMATTYPE)MetaBufferUtil::getIntAt(hnd, 0, MetaBufferUtil::INT_COLORFORMAT);
2619 
2620                         memset(&fmt, 0, sizeof(fmt));
2621                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
2622                                 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
2623                             DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
2624                             DEBUG_PRINT_ERROR(" This leads to unknown color space");
2625                         }
2626                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
2627                             if (is_csc_enabled) {
2628                                 struct v4l2_control control;
2629                                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
2630                                 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
2631                                 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2632                                     DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
2633                                 } else {
2634                                     DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
2635                                     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
2636                                     venc_set_colorspace(MSM_VIDC_BT709_5, 0,
2637                                             MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
2638                                 }
2639                             } else {
2640                                 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
2641                                         MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
2642                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
2643                             }
2644                         }
2645                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2646                         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
2647                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
2648                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
2649                         if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED ||
2650                             usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI) {
2651                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
2652                         }
2653 
2654                         if (color_format > 0 && !venc_set_color_format(color_format)) {
2655                             DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
2656                             return false;
2657                         }
2658 
2659                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2660                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
2661                             return false;
2662                         }
2663                     }
2664 
2665                     // Setting batch mode is sticky. We do not expect camera to change
2666                     // between batch and normal modes at runtime.
2667                     if (mBatchSize) {
2668                         if ((unsigned int)MetaBufferUtil::getBatchSize(hnd) != mBatchSize) {
2669                             DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
2670                                     mBatchSize, MetaBufferUtil::getBatchSize(hnd));
2671                             return false;
2672                         }
2673 
2674                         return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
2675                     }
2676 
2677                     int offset = MetaBufferUtil::getIntAt(hnd, 0, MetaBufferUtil::INT_OFFSET);
2678                     int length = MetaBufferUtil::getIntAt(hnd, 0, MetaBufferUtil::INT_SIZE);
2679                     if (offset < 0 || length < 0) {
2680                         DEBUG_PRINT_ERROR("Invalid meta buffer handle!");
2681                         return false;
2682                     }
2683                     plane[0].data_offset = offset;
2684                     plane[0].length = length;
2685                     plane[0].bytesused = length;
2686                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
2687                             fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
2688                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
2689                     VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
2690                     private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
2691 
2692                     if (!handle) {
2693                         DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
2694                         return false;
2695                     }
2696                     interlace_flag = is_ubwc_interlaced(handle);
2697 
2698                     if (mUseAVTimerTimestamps) {
2699                         uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
2700                         if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
2701                                 && avTimerTimestampNs > 0) {
2702                             bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
2703                             DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
2704                         }
2705                     }
2706 
2707                     if (!streaming[OUTPUT_PORT]) {
2708                         // Moment of truth... actual colorspace is known here..
2709                         if (getMetaData(handle, GET_COLOR_METADATA, &colorData) == 0) {
2710                             DEBUG_PRINT_INFO("ENC_CONFIG: gralloc Color MetaData colorPrimaries=%d colorRange=%d "
2711                                              "transfer=%d matrixcoefficients=%d"
2712                                              "dynamicMetaDataValid %u dynamicMetaDataLen %u",
2713                                              colorData.colorPrimaries, colorData.range,
2714                                              colorData.transfer, colorData.matrixCoefficients,
2715                                              colorData.dynamicMetaDataValid, colorData.dynamicMetaDataLen);
2716                         }
2717 
2718                         if (!venc_cvp_enable(handle)) {
2719                             DEBUG_PRINT_ERROR("ERROR: Setting CVP enable");
2720                             return false;
2721                         }
2722 
2723                         struct v4l2_format fmt;
2724                         memset(&fmt, 0, sizeof(fmt));
2725                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2726 
2727                         bool isUBWC = ((handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED ||
2728                                         handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI) &&
2729                                        is_gralloc_source_ubwc);
2730 
2731                         char grallocFormatStr[200];
2732                         get_gralloc_format_as_string(grallocFormatStr, sizeof(grallocFormatStr), handle->format);
2733                         DEBUG_PRINT_LOW("gralloc format 0x%x (%s) (%s)",
2734                             handle->format, grallocFormatStr, isUBWC ? "UBWC" : "Linear");
2735 
2736                         if (m_codec == OMX_VIDEO_CodingHEVC && (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC ||
2737                             handle->format == HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS) &&
2738                             codec_profile.profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)
2739                             {
2740                                 if (!venc_set_profile (OMX_VIDEO_HEVCProfileMain10)) {
2741                                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile OMX_VIDEO_HEVCProfileMain10");
2742                                     return false;
2743                                 }
2744                             }
2745                         if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
2746                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
2747                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
2748                         } else if (handle->format == HAL_PIXEL_FORMAT_NV12_HEIF) {
2749                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_512;
2750                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12_512");
2751                         } else if (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
2752                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
2753                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12_UBWC");
2754                         } else if (handle->format == VIDC_HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX) {
2755                              m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
2756                              DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 FLEX");
2757                         } else if (handle->format == VIDC_HAL_PIXEL_FORMAT_NV12_UBWC_FLEX) {
2758                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
2759                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 UBWC FLEX");
2760                         } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
2761                             // In case of RGB, conversion to YUV is handled within encoder.
2762                             // Disregard the Colorspace in gralloc-handle in case of RGB and use
2763                             //   [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
2764                             //   [b] 601 for UBWC case     : Venus can convert to 601-LR or FR. use LR for now.
2765                             //set colormetadata corresponding to ITU_R_601;
2766                             colorData.colorPrimaries =  ColorPrimaries_BT601_6_525;
2767                             colorData.range = Range_Limited;
2768                             colorData.transfer = Transfer_SMPTE_170M;
2769                             colorData.matrixCoefficients = MatrixCoEff_BT601_6_525;
2770                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
2771                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
2772                         } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
2773                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
2774                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
2775                         } else if (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC ||
2776                                    handle->format == HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS) {
2777                             if (((m_codec == OMX_VIDEO_CodingHEVC) &&
2778                                  (codec_profile.profile == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)) ||
2779                                      (csc_enable == true)) {
2780                                 m_sVenc_cfg.inputformat =
2781                                     (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC)?
2782                                              V4L2_PIX_FMT_NV12_TP10_UBWC :
2783                                              V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
2784                                 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = 10bit");
2785                             } else {
2786                                 DEBUG_PRINT_ERROR("ENC_CONFIG: 10bit colorformat not supported for this codec and profile");
2787                                 return false;
2788                             }
2789 
2790                             if(colorData.masteringDisplayInfo.colorVolumeSEIEnabled ||
2791                                colorData.contentLightLevel.lightLevelSEIEnabled) {
2792                                 if (!venc_set_hdr_info(colorData.masteringDisplayInfo, colorData.contentLightLevel)) {
2793                                     DEBUG_PRINT_ERROR("HDR10-PQ Info Setting failed");
2794                                     return false;
2795                                 } else {
2796                                     DEBUG_PRINT_INFO("Encoding in HDR10-PQ mode");
2797                                 }
2798                             } else {
2799                                 DEBUG_PRINT_INFO("Encoding in HLG mode");
2800                             }
2801                         } else if (handle->format == QOMX_COLOR_FormatYVU420SemiPlanar) {
2802                            m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
2803                            DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV21 Linear");
2804                         } else {
2805                             DEBUG_PRINT_ERROR("Color format is not recoganized. Format 0x%X", handle->format);
2806                             return false;
2807                         }
2808 
2809                         DEBUG_PRINT_INFO("color_space.primaries %d colorData.colorPrimaries %d, is_csc_custom_matrix_enabled=%d",
2810                                          color_space.primaries, colorData.colorPrimaries, is_csc_custom_matrix_enabled);
2811 
2812                         if (csc_enable) {
2813                             struct v4l2_control control;
2814                             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
2815                             control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
2816                             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2817                                 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC");
2818                             }
2819                             else {
2820                                 if (is_csc_custom_matrix_enabled) {
2821                                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX;
2822                                     control.value = 1;
2823                                     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
2824                                         DEBUG_PRINT_ERROR("venc_empty_buf: Failed to enable VPE CSC custom matrix");
2825                                     } else {
2826                                         DEBUG_PRINT_INFO("venc_empty_buf: Enabled VPE CSC custom matrix");
2827                                     }
2828                                 }
2829                             }
2830                         }
2831 
2832                         /* Enum values from gralloc ColorMetaData matches with the driver values
2833                            as it is standard compliant */
2834                         venc_set_colorspace(colorData.colorPrimaries, colorData.range,
2835                                             colorData.transfer, colorData.matrixCoefficients);
2836                         if ((handle->format == VIDC_HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX) ||
2837                                 (handle->format == VIDC_HAL_PIXEL_FORMAT_NV12_UBWC_FLEX)) {
2838                             if (!venc_superframe_enable(handle)) {
2839                                 DEBUG_PRINT_ERROR("ERROR: Enabling Superframe");
2840                                 return false;
2841                             }
2842                         }
2843 
2844                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
2845                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
2846                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
2847                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
2848                             DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
2849                             return false;
2850                         }
2851                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
2852                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
2853                             return false;
2854                         }
2855                     } else {
2856                         if (m_hdr10meta_enabled) {
2857                             if (getMetaData(handle, GET_COLOR_METADATA, &colorData) == 0) {
2858                                 DEBUG_PRINT_INFO("ENC_CONFIG: gralloc Color MetaData dynamicMetaDataValid=%u dynamicMetaDataLen=%u",
2859                                                  colorData.dynamicMetaDataValid, colorData.dynamicMetaDataLen);
2860                             }
2861                         }
2862                     } // Check OUTPUT Streaming
2863 
2864                     if (!venc_get_cvp_metadata(handle, &buf))
2865                         return false;
2866 
2867                     struct UBWCStats cam_ubwc_stats[2];
2868                     unsigned long long int compression_ratio = 1 << 16;
2869 
2870                     if (getMetaData(handle, GET_UBWC_CR_STATS_INFO, (void *)cam_ubwc_stats) == 0) {
2871                         if (cam_ubwc_stats[0].bDataValid) {
2872                             switch (cam_ubwc_stats[0].version) {
2873                             case UBWC_2_0:
2874                             case UBWC_3_0:
2875                             case UBWC_4_0:
2876                                 {
2877                                     unsigned long long int sum = 0, weighted_sum = 0;
2878 
2879                                     DEBUG_PRINT_HIGH("Field 0 : 32 Tile = %d 64 Tile = %d 96 Tile = %d "
2880                                        "128 Tile = %d 160 Tile = %d 192 Tile = %d 256 Tile = %d\n",
2881                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile32,
2882                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile64,
2883                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile96,
2884                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile128,
2885                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile160,
2886                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile192,
2887                                        cam_ubwc_stats[0].ubwc_stats.nCRStatsTile256);
2888 
2889                                     weighted_sum =
2890                                         32  * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile32 +
2891                                         64  * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile64 +
2892                                         96  * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile96 +
2893                                         128 * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile128 +
2894                                         160 * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile160 +
2895                                         192 * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile192 +
2896                                         256 * cam_ubwc_stats[0].ubwc_stats.nCRStatsTile256;
2897 
2898                                     sum =
2899                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile32 +
2900                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile64 +
2901                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile96 +
2902                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile128 +
2903                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile160 +
2904                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile192 +
2905                                         cam_ubwc_stats[0].ubwc_stats.nCRStatsTile256;
2906 
2907                                     compression_ratio = (weighted_sum && sum) ?
2908                                         ((256 * sum) << 16) / weighted_sum : compression_ratio;
2909                                 }
2910                                 break;
2911                             default:
2912                                 break;
2913                             }
2914                         }
2915                     }
2916 
2917                     uint32_t encodePerfMode = 0;
2918                     if (getMetaData(handle, GET_VIDEO_PERF_MODE, &encodePerfMode) == 0) {
2919                         if (encodePerfMode == OMX_TRUE)
2920                             buf.flags |= V4L2_BUF_FLAG_PERF_MODE;
2921                         // Clear SET_VIDEO_PERF_MODE in buffer handle
2922                         setMetaData(handle, SET_VIDEO_PERF_MODE, 0);
2923                     }
2924                     fd = handle->fd;
2925                     plane[0].data_offset = 0;
2926                     plane[0].length = handle->size;
2927                     plane[0].bytesused = handle->size;
2928                     plane[0].reserved[MSM_VIDC_COMP_RATIO] = (unsigned long int)compression_ratio;
2929                     char v4l2ColorFormatStr[200];
2930                     get_v4l2_color_format_as_string(v4l2ColorFormatStr, sizeof(v4l2ColorFormatStr), m_sVenc_cfg.inputformat);
2931                     DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
2932                                 ": filled %d of %d format 0x%lx (%s) CR %d", fd, plane[0].bytesused,
2933                                 plane[0].length, m_sVenc_cfg.inputformat, v4l2ColorFormatStr, plane[0].reserved[MSM_VIDC_COMP_RATIO]);
2934                 }
2935             } else {
2936                 // Metadata mode
2937                 // color_format == 1 ==> RGBA to YUV Color-converted buffer
2938                 // Buffers color-converted via C2D have 601 color
2939                 if (!streaming[OUTPUT_PORT]) {
2940                     c2d_enabled = 1;
2941                     DEBUG_PRINT_HIGH("Setting colorspace 601 for Color-converted buffer");
2942                     venc_set_colorspace(MSM_VIDC_BT601_6_625, color_space.range,
2943                             MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
2944                 }
2945                 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
2946                 plane[0].data_offset = bufhdr->nOffset;
2947                 plane[0].length = bufhdr->nAllocLen;
2948                 plane[0].bytesused = bufhdr->nFilledLen;
2949                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
2950                         fd, plane[0].bytesused, plane[0].length);
2951             }
2952         } else { // Not Metadata mode
2953             plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
2954             plane[0].data_offset = bufhdr->nOffset;
2955             plane[0].length = bufhdr->nAllocLen;
2956             plane[0].bytesused = bufhdr->nFilledLen;
2957             DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
2958                     fd, plane[0].bytesused, plane[0].length);
2959         }
2960     }
2961 
2962     if (!handle_dynamic_config(bufhdr)) {
2963         DEBUG_PRINT_ERROR("%s Failed to set dynamic configs", __func__);
2964         return false;
2965     }
2966 
2967     if (!streaming[OUTPUT_PORT]) {
2968         enum v4l2_buf_type buf_type;
2969         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2970         int ret;
2971 
2972         // Some 3rd APPs use NativeRecorder to implement their applications
2973         // like screenrecorder, implicitly enable B-frame may cause issues.
2974         // So disallow implicit B-frame when input format is non-UBWC or RGBA(c2d enabled).
2975         if ((m_sVenc_cfg.inputformat != V4L2_PIX_FMT_NV12_TP10_UBWC &&
2976              m_sVenc_cfg.inputformat != V4L2_PIX_FMT_NV12_UBWC) || c2d_enabled) {
2977             DEBUG_PRINT_HIGH("Disallow implicitly enable B-frames");
2978             if (!set_native_recoder(OMX_FALSE)) {
2979                 DEBUG_PRINT_ERROR("Failed to set Native Recorder");
2980                 return false;
2981             }
2982         }
2983 
2984         venc_set_quality_boost((OMX_BOOL)c2d_enabled);
2985 
2986         if (!downscalar_enabled) {
2987             OMX_U32 inp_width = 0, inp_height = 0, out_width = 0, out_height = 0;
2988 
2989             if (!venc_get_dimensions(PORT_INDEX_IN, &inp_width, &inp_height)) {
2990                 return false;
2991             }
2992 
2993             if (!venc_get_dimensions(PORT_INDEX_OUT, &out_width, &out_height)) {
2994                 return false;
2995             }
2996 
2997             // Tiling in HEIC requires output WxH to be Tile size; difference is permitted
2998             if (!(m_codec == OMX_VIDEO_CodingImageHEIC) &&
2999                 inp_width * inp_height != out_width * out_height) {
3000                 DEBUG_PRINT_ERROR("Downscalar is disabled and input/output dimenstions don't match");
3001                 DEBUG_PRINT_ERROR("Input WxH : %dx%d Output WxH : %dx%d",inp_width, inp_height, out_width, out_height);
3002                 return false;
3003             }
3004         }
3005 
3006         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3007 
3008         if (ret) {
3009             DEBUG_PRINT_ERROR("Failed to call streamon");
3010             if (errno == EBUSY) {
3011                 hw_overload = true;
3012             }
3013             return false;
3014         } else {
3015             streaming[OUTPUT_PORT] = true;
3016         }
3017     }
3018 
3019     extra_idx = EXTRADATA_IDX(num_input_planes);
3020 
3021     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3022         plane[extra_idx].bytesused = input_extradata_info.buffer_size;
3023         plane[extra_idx].length = input_extradata_info.buffer_size;
3024         plane[extra_idx].m.userptr = (unsigned long)input_extradata_info.ion[index].uaddr;
3025 #ifdef USE_ION
3026         plane[extra_idx].reserved[MSM_VIDC_BUFFER_FD] = input_extradata_info.ion[index].data_fd;
3027 #endif
3028         plane[extra_idx].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3029         plane[extra_idx].data_offset = 0;
3030     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3031         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3032         return false;
3033     }
3034 
3035     buf.index = index;
3036     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3037     buf.memory = V4L2_MEMORY_USERPTR;
3038     plane[0].reserved[MSM_VIDC_BUFFER_FD] = fd;
3039     plane[0].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3040     buf.m.planes = plane;
3041     buf.length = num_input_planes;
3042     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
3043     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
3044 
3045     if (!handle_input_extradata(buf)) {
3046         DEBUG_PRINT_ERROR("%s Failed to handle input extradata", __func__);
3047         return false;
3048     }
3049 
3050     VIDC_TRACE_INT_LOW("ETB-TS", bufhdr->nTimeStamp / 1000);
3051 
3052     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3053         buf.flags |= V4L2_BUF_FLAG_EOS;
3054 
3055     if (!plane[0].bytesused) {
3056         if (buf.flags & V4L2_BUF_FLAG_EOS) {
3057             DEBUG_PRINT_ERROR("venc_empty_buf: Zero length EOS buffers are not valid");
3058             DEBUG_PRINT_ERROR("Use this function instead : venc_handle_empty_eos_buffer");
3059             return false;
3060         }
3061         DEBUG_PRINT_ERROR("venc_empty_buf: Zero length buffers are not valid");
3062         return false;
3063     }
3064 
3065     if (m_debug.in_buffer_log) {
3066         venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat, interlace_flag);
3067     }
3068     if (m_debug.extradata_log && extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3069         DEBUG_PRINT_ERROR("Extradata Addr 0x%llx, Buffer Addr = 0x%x",
3070             (OMX_U64)input_extradata_info.ion[index].uaddr, (unsigned int)plane[index].m.userptr);
3071         venc_extradata_log_buffers((char *)plane[extra_idx].m.userptr, index, true);
3072     }
3073     print_v4l2_buffer("QBUF-ETB", &buf);
3074     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3075 
3076     if (rc) {
3077         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
3078         return false;
3079     }
3080 
3081     etb++;
3082 
3083     return true;
3084 }
3085 
get_media_colorformat(unsigned long inputformat)3086 unsigned long venc_dev::get_media_colorformat(unsigned long inputformat)
3087 {
3088     unsigned long color_format;
3089     switch (inputformat) {
3090         case V4L2_PIX_FMT_NV12:
3091             color_format = COLOR_FMT_NV12;
3092             break;
3093         case V4L2_PIX_FMT_NV12_512:
3094             color_format = COLOR_FMT_NV12_512;
3095             break;
3096         case V4L2_PIX_FMT_NV12_UBWC:
3097             color_format = COLOR_FMT_NV12_UBWC;
3098             break;
3099         case V4L2_PIX_FMT_RGB32:
3100             color_format = COLOR_FMT_RGBA8888;
3101             break;
3102         case V4L2_PIX_FMT_RGBA8888_UBWC:
3103             color_format = COLOR_FMT_RGBA8888_UBWC;
3104             break;
3105         case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
3106             color_format = COLOR_FMT_P010;
3107             break;
3108         case V4L2_PIX_FMT_NV12_TP10_UBWC:
3109             color_format = COLOR_FMT_NV12_BPP10_UBWC;
3110             break;
3111         default:
3112             color_format = COLOR_FMT_NV12_UBWC;
3113             DEBUG_PRINT_ERROR("Unknown format %lx,default to NV12_UBWC", inputformat);
3114             break;
3115     }
3116     return color_format;
3117 }
3118 
venc_empty_batch(OMX_BUFFERHEADERTYPE * bufhdr,unsigned index)3119 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
3120 {
3121     struct v4l2_buffer buf;
3122     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3123     int rc = 0, extra_idx, numBufs;
3124     struct v4l2_control control;
3125     LEGACY_CAM_METADATA_TYPE * meta_buf = NULL;
3126     native_handle_t *hnd = NULL;
3127 
3128     if (bufhdr == NULL) {
3129         DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
3130         return false;
3131     }
3132 
3133     bool status = true;
3134     if (metadatamode) {
3135         plane[0].m.userptr = index;
3136         meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
3137 
3138         if (!color_format) {
3139             if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) {
3140                 hnd = (native_handle_t*)meta_buf->meta_handle;
3141                 if (!hnd) {
3142                     DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
3143                     return false;
3144                 } else if (MetaBufferUtil::getBatchSize(hnd) > kMaxBuffersInBatch) {
3145                     DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
3146                             "Max = %d", MetaBufferUtil::getBatchSize(hnd), kMaxBuffersInBatch);
3147                     status = false;
3148                 }
3149                 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", MetaBufferUtil::getBatchSize(hnd));
3150             } else {
3151                 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
3152                 status = false;
3153             }
3154         } else {
3155             DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
3156             status = false;
3157         }
3158     } else {
3159         DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
3160         status = false;
3161     }
3162 
3163     if (status) {
3164         OMX_TICKS bufTimeStamp = 0ll;
3165         int numBufs = MetaBufferUtil::getBatchSize(hnd);
3166         int v4l2Ids[kMaxBuffersInBatch] = {-1};
3167         for (int i = 0; i < numBufs; ++i) {
3168             v4l2Ids[i] = mBatchInfo.registerBuffer(index);
3169             if (v4l2Ids[i] < 0) {
3170                 DEBUG_PRINT_ERROR("Failed to register buffer");
3171                 // TODO: cleanup the map and purge all slots of current index
3172                 status = false;
3173                 break;
3174             }
3175         }
3176         for (int i = 0; i < numBufs; ++i) {
3177             int v4l2Id = v4l2Ids[i];
3178             int usage = 0;
3179 
3180             memset(&buf, 0, sizeof(buf));
3181             memset(&plane, 0, sizeof(plane));
3182 
3183             DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
3184             buf.index = (unsigned)v4l2Id;
3185             buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3186             buf.memory = V4L2_MEMORY_USERPTR;
3187             plane[0].reserved[MSM_VIDC_BUFFER_FD] = MetaBufferUtil::getFdAt(hnd, i);
3188             plane[0].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3189             plane[0].data_offset = MetaBufferUtil::getIntAt(hnd, i, MetaBufferUtil::INT_OFFSET);
3190             plane[0].m.userptr = (unsigned long)meta_buf;
3191             plane[0].length = plane[0].bytesused = MetaBufferUtil::getIntAt(hnd, i, MetaBufferUtil::INT_SIZE);
3192             buf.m.planes = plane;
3193             buf.length = num_input_planes;
3194 
3195             usage = MetaBufferUtil::getIntAt(hnd, i, MetaBufferUtil::INT_USAGE);
3196             usage = usage > 0 ? usage : 0;
3197 
3198             extra_idx = EXTRADATA_IDX(num_input_planes);
3199 
3200             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3201                 plane[extra_idx].bytesused = input_extradata_info.buffer_size;
3202                 plane[extra_idx].length = input_extradata_info.buffer_size;
3203                 plane[extra_idx].m.userptr = (unsigned long)input_extradata_info.ion[v4l2Id].uaddr;
3204                 plane[extra_idx].reserved[MSM_VIDC_BUFFER_FD] = input_extradata_info.ion[v4l2Id].data_fd;
3205                 plane[extra_idx].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3206                 plane[extra_idx].data_offset = 0;
3207             } else if (extra_idx >= VIDEO_MAX_PLANES) {
3208                 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
3209                 return false;
3210             }
3211 
3212             if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
3213                 buf.flags |= V4L2_BUF_FLAG_EOS;
3214 
3215             // timestamp differences from camera are in nano-seconds
3216             bufTimeStamp = bufhdr->nTimeStamp + MetaBufferUtil::getIntAt(hnd, i, MetaBufferUtil::INT_TIMESTAMP) / 1000;
3217 
3218             DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
3219                 i, numBufs, bufhdr, plane[0].reserved[MSM_VIDC_BUFFER_FD], plane[0].length, bufTimeStamp);
3220             buf.timestamp.tv_sec = bufTimeStamp / 1000000;
3221             buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
3222 
3223             if (!handle_input_extradata(buf)) {
3224                 DEBUG_PRINT_ERROR("%s Failed to handle input extradata", __func__);
3225                 return false;
3226             }
3227 
3228             if (!handle_dynamic_config(bufhdr)) {
3229                 DEBUG_PRINT_ERROR("%s Failed to set dynamic configs", __func__);
3230                 return false;
3231             }
3232 
3233             VIDC_TRACE_INT_LOW("ETB-TS", bufTimeStamp / 1000);
3234 
3235             print_v4l2_buffer("QBUF-ETB", &buf);
3236             rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3237             if (rc) {
3238                 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
3239                 return false;
3240             }
3241 
3242             etb++;
3243         }
3244     }
3245 
3246     if (status && !streaming[OUTPUT_PORT]) {
3247         enum v4l2_buf_type buf_type;
3248         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3249         int ret;
3250 
3251         if (!downscalar_enabled) {
3252             OMX_U32 inp_width = 0, inp_height = 0, out_width = 0, out_height = 0;
3253 
3254             if (!venc_get_dimensions(PORT_INDEX_IN, &inp_width, &inp_height)) {
3255                 return false;
3256             }
3257 
3258             if (!venc_get_dimensions(PORT_INDEX_OUT, &out_width, &out_height)) {
3259                 return false;
3260             }
3261 
3262             if (inp_width * inp_height != out_width * out_height) {
3263                 DEBUG_PRINT_ERROR("Downscalar is disabled and input/output dimenstions don't match");
3264                 DEBUG_PRINT_ERROR("Input WxH : %dx%d Output WxH : %dx%d",inp_width, inp_height, out_width, out_height);
3265                 return false;
3266             }
3267         }
3268 
3269         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
3270         if (ret) {
3271             DEBUG_PRINT_ERROR("Failed to call streamon");
3272             if (errno == EBUSY) {
3273                 hw_overload = true;
3274             }
3275             status = false;
3276         } else {
3277             streaming[OUTPUT_PORT] = true;
3278         }
3279     }
3280 
3281     return status;
3282 }
3283 
venc_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)3284 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
3285 {
3286     struct pmem *temp_buffer = NULL;
3287     struct venc_buffer  frameinfo;
3288     struct v4l2_buffer buf;
3289     struct v4l2_plane plane[VIDEO_MAX_PLANES];
3290     int rc = 0;
3291     unsigned int extra_idx;
3292     struct OMX_BUFFERHEADERTYPE *bufhdr;
3293 
3294     if (buffer == NULL)
3295         return false;
3296 
3297     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
3298 
3299     if (pmem_data_buf) {
3300         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
3301         plane[0].m.userptr = (unsigned long)pmem_data_buf;
3302     } else {
3303         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
3304         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
3305     }
3306 
3307     memset(&buf, 0, sizeof(buf));
3308     memset(&plane, 0, sizeof(plane));
3309 
3310     buf.index = index;
3311     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3312     buf.memory = V4L2_MEMORY_USERPTR;
3313     plane[0].length = bufhdr->nAllocLen;
3314     plane[0].bytesused = bufhdr->nFilledLen;
3315     plane[0].reserved[MSM_VIDC_BUFFER_FD] = fd;
3316     plane[0].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3317     plane[0].data_offset = bufhdr->nOffset;
3318     buf.m.planes = plane;
3319     buf.length = num_output_planes;
3320     buf.flags = 0;
3321 
3322     if (venc_handle->is_secure_session()) {
3323         if (venc_handle->allocate_native_handle) {
3324             native_handle_t *handle_t = (native_handle_t *)(bufhdr->pBuffer);
3325             plane[0].length = handle_t->data[3];
3326         } else {
3327             output_metabuffer *meta_buf = (output_metabuffer *)(bufhdr->pBuffer);
3328             native_handle_t *handle_t = meta_buf->nh;
3329             plane[0].length = handle_t->data[3];
3330         }
3331     }
3332 
3333     extra_idx = EXTRADATA_IDX(num_output_planes);
3334 
3335     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3336         plane[extra_idx].bytesused = output_extradata_info.buffer_size;
3337         plane[extra_idx].length = output_extradata_info.buffer_size;
3338         plane[extra_idx].m.userptr = (unsigned long)output_extradata_info.ion[index].uaddr;
3339 #ifdef USE_ION
3340         plane[extra_idx].reserved[MSM_VIDC_BUFFER_FD] = output_extradata_info.ion[index].data_fd;
3341 #endif
3342         plane[extra_idx].reserved[MSM_VIDC_DATA_OFFSET] = 0;
3343         plane[extra_idx].data_offset = 0;
3344     } else if (extra_idx >= VIDEO_MAX_PLANES) {
3345         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
3346         return false;
3347     }
3348 
3349     print_v4l2_buffer("QBUF-FTB", &buf);
3350     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
3351 
3352     if (rc) {
3353         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
3354         return false;
3355     }
3356 
3357     ftb++;
3358     return true;
3359 }
3360 
venc_set_colorspace(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer_chars,OMX_U32 matrix_coeffs)3361 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
3362     OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
3363 {
3364     int rc;
3365     struct v4l2_control control;
3366 
3367     DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
3368         primaries, range, transfer_chars, matrix_coeffs);
3369 
3370     control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
3371     control.value = primaries;
3372 
3373     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3374     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3375 
3376     if (rc) {
3377         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
3378         return false;
3379     }
3380 
3381     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3382 
3383     color_space.primaries = control.value;
3384 
3385     control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
3386     control.value = range;
3387 
3388     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3389     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3390 
3391     if (rc) {
3392         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
3393         return false;
3394     }
3395 
3396     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3397 
3398     color_space.range = control.value;
3399 
3400     control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
3401     control.value = transfer_chars;
3402 
3403     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3404     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3405 
3406     if (rc) {
3407         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
3408         return false;
3409     }
3410 
3411     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3412 
3413     color_space.transfer_chars = control.value;
3414 
3415     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
3416     control.value = matrix_coeffs;
3417 
3418     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3419     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3420 
3421     if (rc) {
3422         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
3423         return false;
3424     }
3425 
3426     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3427 
3428     color_space.matrix_coeffs = control.value;
3429 
3430     return true;
3431 }
3432 
venc_set_qp(OMX_U32 i_frame_qp,OMX_U32 p_frame_qp,OMX_U32 b_frame_qp,OMX_U32 enable)3433 bool venc_dev::venc_set_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp, OMX_U32 enable)
3434 {
3435     int rc;
3436     struct v4l2_control control;
3437 
3438     OMX_U32 ids[3] = {
3439         V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
3440         V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
3441         V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP
3442     };
3443 
3444     OMX_U32 qp_values[3] = {
3445         i_frame_qp,
3446         p_frame_qp,
3447         b_frame_qp
3448     };
3449     unsigned long *session_qp_values[3] = {
3450         &session_qp.iframeqp,
3451         &session_qp.pframeqp,
3452         &session_qp.bframeqp
3453     };
3454     OMX_U32 qp_mask[3] = {
3455         ENABLE_I_QP,
3456         ENABLE_P_QP,
3457         ENABLE_B_QP
3458     };
3459 
3460     for(int i=0; i<3; i++) {
3461         if (enable & qp_mask[i]) {
3462             control.id = ids[i];
3463             control.value = qp_values[i];
3464 
3465             DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3466             rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3467 
3468             if (rc) {
3469                 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3470                 return false;
3471             }
3472             DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3473             *session_qp_values[i] = control.value;
3474         }
3475     }
3476 
3477     return true;
3478 }
3479 
set_nP_frames(unsigned long nPframes)3480 bool venc_dev::set_nP_frames(unsigned long nPframes)
3481 {
3482     struct v4l2_control control;
3483 
3484     control.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
3485     control.value = (nPframes > VENC_INFINITE_GOP) ? VENC_INFINITE_GOP : nPframes;
3486     int rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3487 
3488     if (rc) {
3489         DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3490         return false;
3491     }
3492     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3493 
3494     return true;
3495 }
3496 
set_nB_frames(unsigned long nBframes)3497 bool venc_dev::set_nB_frames(unsigned long nBframes)
3498 {
3499     struct v4l2_control control;
3500 
3501     control.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
3502     control.value = (nBframes > VENC_INFINITE_GOP) ? VENC_INFINITE_GOP : nBframes;
3503     int rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3504 
3505     if (rc) {
3506         DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3507         return false;
3508     }
3509     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3510 
3511     return true;
3512 }
3513 
set_native_recoder(bool enable)3514 bool venc_dev::set_native_recoder(bool enable)
3515 {
3516     struct v4l2_control control;
3517 
3518     control.id = V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER;
3519     control.value = enable;
3520     int rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3521 
3522     if (rc) {
3523         DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3524         return false;
3525     }
3526     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3527 
3528     return true;
3529 }
3530 
venc_set_intra_refresh()3531 bool venc_dev::venc_set_intra_refresh()
3532 {
3533     int rc;
3534     struct v4l2_control control_mode;
3535 
3536     // Default is RANDOM mode
3537     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
3538     // Set intra refresh period (frame count) for Random mode
3539     control_mode.value  = intra_refresh.framecount;
3540 
3541     if (intra_refresh.irmode == OMX_VIDEO_IntraRefreshCyclic) {
3542         control_mode.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
3543         control_mode.value  = intra_refresh.mbcount;
3544     }
3545 
3546     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d",
3547                     control_mode.id, control_mode.value);
3548     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
3549 
3550     if (rc) {
3551         DEBUG_PRINT_HIGH("Failed to set control, id %#x, value %d",
3552                          control_mode.id, control_mode.value);
3553         // This key is ignored if the video encoder does not support the intra refresh feature.
3554         // From android developer reference documentation.
3555     }
3556 
3557     return true;
3558 }
3559 
venc_set_target_bitrate(OMX_U32 nTargetBitrate)3560 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate)
3561 {
3562     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
3563             (unsigned int)nTargetBitrate);
3564     struct v4l2_control control;
3565     int rc = 0;
3566     OMX_U32 ids[2] = {
3567         V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY,
3568         V4L2_CID_MPEG_VIDEO_BITRATE
3569     };
3570 
3571     control.id =  ids[!!(rate_ctrl.rcmode ^ V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)];
3572     control.value = nTargetBitrate;
3573 
3574     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3575     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3576     if (rc) {
3577         DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3578         return false;
3579     }
3580 
3581     bitrate.target_bitrate = control.value;
3582     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
3583 
3584     return true;
3585 }
3586 
venc_set_encode_framerate(OMX_U32 encode_framerate)3587 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate)
3588 {
3589     int rc = 0;
3590     struct venc_framerate frame_rate_cfg;
3591     struct v4l2_control control;
3592 
3593     control.id =  V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
3594     control.value = encode_framerate;
3595 
3596     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
3597     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3598     if (rc) {
3599         DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
3600         return false;
3601     }
3602 
3603     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
3604     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
3605     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
3606 
3607     return true;
3608 }
3609 
venc_get_color_format(OMX_COLOR_FORMATTYPE eColorFormat)3610 unsigned long venc_dev::venc_get_color_format(OMX_COLOR_FORMATTYPE eColorFormat)
3611 {
3612     unsigned long format = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
3613 
3614     switch ((int)eColorFormat) {
3615     case OMX_COLOR_FormatYUV420SemiPlanar:
3616     case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
3617         format = V4L2_PIX_FMT_NV12;
3618         break;
3619     case QOMX_COLOR_FormatYVU420SemiPlanar:
3620         format = V4L2_PIX_FMT_NV21;
3621         break;
3622     case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
3623         format = V4L2_PIX_FMT_NV12_UBWC;
3624         break;
3625     case QOMX_COLOR_Format32bitRGBA8888:
3626         format = V4L2_PIX_FMT_RGB32;
3627         break;
3628     case QOMX_COLOR_Format32bitRGBA8888Compressed:
3629         format = V4L2_PIX_FMT_RGBA8888_UBWC;
3630         break;
3631     case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed:
3632         format = V4L2_PIX_FMT_NV12_TP10_UBWC;
3633         break;
3634     case QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus:
3635         format = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
3636         break;
3637     default:
3638         DEBUG_PRINT_INFO("WARN: Unsupported eColorFormat %#x", eColorFormat);
3639         format = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
3640         break;
3641     }
3642 
3643     if (m_codec == OMX_VIDEO_CodingImageHEIC)
3644         format = V4L2_PIX_FMT_NV12_512;
3645 
3646     return format;
3647 }
3648 
venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)3649 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
3650 {
3651     struct v4l2_format fmt;
3652     int color_space = 0;
3653     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
3654 
3655     switch ((int)color_format) {
3656         case OMX_COLOR_FormatYUV420SemiPlanar:
3657         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
3658             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
3659             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
3660             break;
3661         case QOMX_COLOR_FormatYVU420SemiPlanar:
3662             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
3663             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
3664             break;
3665         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
3666             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
3667             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
3668             break;
3669         case QOMX_COLOR_Format32bitRGBA8888:
3670             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
3671             break;
3672         case QOMX_COLOR_Format32bitRGBA8888Compressed:
3673             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
3674             break;
3675         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed:
3676             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_TP10_UBWC;
3677             break;
3678         case QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus:
3679             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
3680             break;
3681         default:
3682             DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
3683             m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
3684             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
3685             DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
3686             break;
3687     }
3688 
3689     if (m_codec == OMX_VIDEO_CodingImageHEIC)
3690         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_512;
3691 
3692     memset(&fmt, 0, sizeof(fmt));
3693     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3694     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
3695     fmt.fmt.pix_mp.colorspace = color_space;
3696     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3697     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3698 
3699     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3700         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
3701         return false;
3702     }
3703 
3704     return true;
3705 }
3706 
venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)3707 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
3708 {
3709     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
3710 
3711     if (intra_vop_refresh == OMX_TRUE) {
3712         struct v4l2_control control;
3713         int rc;
3714         control.id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME;
3715         control.value = 1;
3716 
3717         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3718         if (rc) {
3719             DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
3720             return false;
3721         }
3722         DEBUG_PRINT_HIGH("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3723     } else {
3724         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
3725     }
3726 
3727     return true;
3728 }
3729 
venc_set_max_hierp_layer()3730 OMX_ERRORTYPE venc_dev::venc_set_max_hierp_layer()
3731 {
3732     DEBUG_PRINT_LOW("venc_set_max_hierp_layer");
3733     struct v4l2_control control;
3734 
3735     DEBUG_PRINT_LOW("Setting hierp max layer: %u",
3736                     temporal_layers_config.nMaxLayers);
3737 
3738     control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER;
3739     control.value = temporal_layers_config.nMaxLayers;
3740 
3741     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3742         DEBUG_PRINT_ERROR("Failed to set max HP layers: %u", control.value);
3743         return OMX_ErrorUnsupportedSetting;
3744     }
3745     return OMX_ErrorNone;
3746 }
3747 
venc_set_hierp_layer()3748 OMX_ERRORTYPE venc_dev::venc_set_hierp_layer()
3749 {
3750     DEBUG_PRINT_LOW("venc_set_hierp_layer");
3751     struct v4l2_control control;
3752 
3753     DEBUG_PRINT_LOW("Setting hierp layer: %u", temporal_layers_config.nPLayers);
3754 
3755     control.id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER;
3756     control.value = temporal_layers_config.nPLayers;
3757 
3758     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3759         DEBUG_PRINT_ERROR("Failed to set HP layers: %u", control.value);
3760         return OMX_ErrorUnsupportedSetting;
3761     }
3762     return OMX_ErrorNone;
3763 }
3764 
venc_set_ltrcount(OMX_U32 count)3765 bool venc_dev::venc_set_ltrcount(OMX_U32 count)
3766 {
3767     DEBUG_PRINT_LOW("venc_set_ltrcount: count = %u", (unsigned int)count);
3768     struct v4l2_control control;
3769 
3770     control.id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
3771     control.value = count;
3772 
3773     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3774         DEBUG_PRINT_ERROR("Failed to set LTR count: %u", control.value);
3775         return OMX_ErrorUnsupportedSetting;
3776     }
3777 
3778     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3779                     control.id, control.value);
3780     return true;
3781 }
3782 
venc_set_useltr(OMX_U32 frameIdx)3783 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
3784 {
3785     DEBUG_PRINT_LOW("venc_use_goldenframe");
3786     int rc = true;
3787     struct v4l2_control control;
3788 
3789     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
3790     control.value = frameIdx;
3791 
3792     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3793     if (rc) {
3794         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
3795         return false;
3796     }
3797 
3798     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3799                     control.id, control.value);
3800     return true;
3801 }
3802 
venc_set_markltr(OMX_U32 frameIdx)3803 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
3804 {
3805     DEBUG_PRINT_LOW("venc_set_goldenframe");
3806     int rc = true;
3807     struct v4l2_control control;
3808 
3809     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
3810     control.value = frameIdx;
3811 
3812     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3813     if (rc) {
3814         DEBUG_PRINT_ERROR("Failed to set markltr %d", rc);
3815         return false;
3816     }
3817 
3818     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3819                     control.id, control.value);
3820     return true;
3821 }
3822 
venc_set_mirror(OMX_MIRRORTYPE mirror)3823 bool venc_dev::venc_set_mirror(OMX_MIRRORTYPE mirror)
3824 {
3825     DEBUG_PRINT_LOW("venc_set_mirror");
3826     int rc = true;
3827     struct v4l2_control control[2];
3828 
3829     control[0].id = V4L2_CID_VFLIP;
3830     control[0].value = V4L2_MPEG_MSM_VIDC_DISABLE;
3831     control[1].id = V4L2_CID_HFLIP;
3832     control[1].value = V4L2_MPEG_MSM_VIDC_DISABLE;
3833 
3834     if (mirror == OMX_MirrorVertical || mirror == OMX_MirrorBoth) {
3835         control[0].value = V4L2_MPEG_MSM_VIDC_ENABLE;
3836     }
3837     if (mirror == OMX_MirrorHorizontal || mirror == OMX_MirrorBoth) {
3838         control[1].value = V4L2_MPEG_MSM_VIDC_ENABLE;
3839     }
3840 
3841     for(int i=0; i<2; i++) {
3842         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control[i]);
3843         if (rc) {
3844             DEBUG_PRINT_ERROR("Failed to set mirror %d", rc);
3845             return false;
3846         }
3847         DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
3848                         control[i].id, control[i].value);
3849     }
3850 
3851     return true;
3852 }
3853 
venc_set_vpe_rotation(OMX_S32 rotation_angle)3854 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
3855 {
3856     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
3857     struct v4l2_control control;
3858     int rc;
3859     struct v4l2_format fmt;
3860     struct v4l2_requestbuffers bufreq;
3861 
3862     if ((OMX_S32)m_rotation.rotation == rotation_angle) {
3863         DEBUG_PRINT_HIGH("venc_set_vpe_rotation: rotation (%d) not changed", rotation_angle);
3864         return true;
3865     }
3866 
3867     control.id = V4L2_CID_ROTATE;
3868     control.value = rotation_angle;
3869 
3870     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
3871     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
3872     if (rc) {
3873         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
3874         return false;
3875     }
3876     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
3877 
3878     /* successfully set rotation_angle, save it */
3879     m_rotation.rotation = rotation_angle;
3880 
3881     return true;
3882 }
3883 
venc_prepare_c2d_rotation(OMX_S32 rotation_angle)3884 bool venc_dev::venc_prepare_c2d_rotation(OMX_S32 rotation_angle)
3885 {
3886    int rc;
3887    struct v4l2_format fmt;
3888    struct v4l2_requestbuffers bufreq;
3889    OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3890 
3891     DEBUG_PRINT_HIGH("venc_prepare_c2d_rotation angle = %d", (int)rotation_angle);
3892     if ((OMX_S32)m_rotation.rotation == rotation_angle) {
3893         DEBUG_PRINT_HIGH("venc_prepare_c2d_rotation: rotation (%d) not changed", rotation_angle);
3894         return true;
3895     }
3896 
3897     if (rotation_angle == 90 || rotation_angle == 270) {
3898         m_bDimensionsNeedFlip = true;
3899         portDefn = &venc_handle->m_sInPortDef;
3900         m_sVenc_cfg.input_height = portDefn->format.video.nFrameWidth;
3901         m_sVenc_cfg.input_width =  portDefn->format.video.nFrameHeight;
3902 
3903         memset(&fmt, 0, sizeof(fmt));
3904 
3905         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3906         if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
3907             DEBUG_PRINT_ERROR("Failed to get format on OUTPUT_MPLANE");
3908             return false;
3909         }
3910 
3911         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
3912         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
3913         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3914             DEBUG_PRINT_ERROR("set format failed, type %d, wxh %dx%d",
3915                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
3916                 hw_overload = errno == EBUSY;
3917                 return false;
3918         }
3919         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
3920 
3921         portDefn = &venc_handle->m_sOutPortDef;
3922         m_sVenc_cfg.dvs_width  = portDefn->format.video.nFrameHeight;
3923         m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameWidth;
3924 
3925         memset(&fmt, 0, sizeof(fmt));
3926 
3927         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3928         if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
3929             DEBUG_PRINT_ERROR("Failed to get format on CAPTURE_MPLANE");
3930             return false;
3931         }
3932 
3933         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
3934         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
3935         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
3936             DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
3937             hw_overload = errno == EBUSY;
3938             return false;
3939         }
3940 
3941         m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
3942     }
3943 
3944     /* successfully set rotation_angle, save it */
3945     m_rotation.rotation = rotation_angle;
3946 
3947     return true;
3948 }
3949 
venc_set_baselayerid(OMX_U32 baseid)3950 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
3951 {
3952     struct v4l2_control control;
3953     if (temporal_layers_config.hier_mode == HIER_P) {
3954         control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
3955         control.value = baseid;
3956         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
3957         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3958             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
3959             return false;
3960         }
3961         return true;
3962     } else {
3963         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
3964                 temporal_layers_config.hier_mode);
3965         return false;
3966     }
3967 }
3968 
venc_set_priority(OMX_U32 priority)3969 bool venc_dev::venc_set_priority(OMX_U32 priority) {
3970     struct v4l2_control control;
3971 
3972     DEBUG_PRINT_LOW("venc_set_priority: %s", priority ? "NonRealTime" : "RealTime");
3973     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
3974     if (priority == 0)
3975         control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
3976     else
3977         control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
3978 
3979     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
3980         DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
3981                 priority == 0 ? "ENABLE" : "DISABLE");
3982         return false;
3983     }
3984     return true;
3985 }
3986 
reconfigure_avc_param(OMX_VIDEO_PARAM_AVCTYPE * param)3987 bool venc_dev::reconfigure_avc_param(OMX_VIDEO_PARAM_AVCTYPE *param) {
3988     param->eProfile = (OMX_VIDEO_AVCPROFILETYPE)QOMX_VIDEO_AVCProfileMain;
3989 
3990     DEBUG_PRINT_LOW("reconfigure_avc_param");
3991 
3992     if (!venc_set_profile (param->eProfile)) {
3993         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile %d",
3994             param->eProfile);
3995         return false;
3996     }
3997     if (set_nP_frames(param->nPFrames) == false ||
3998         (param->nBFrames && set_nB_frames(param->nBFrames) == false)) {
3999             DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
4000             return false;
4001     }
4002     if (!venc_set_entropy_config (param->bEntropyCodingCABAC, param->nCabacInitIdc)) {
4003         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
4004         return false;
4005     }
4006     if (!venc_set_inloop_filter (param->eLoopFilterMode)) {
4007         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
4008         return false;
4009     }
4010     if (!venc_set_multislice_cfg(V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB, param->nSliceHeaderSpacing)) {
4011         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
4012         return false;
4013     }
4014     if (!venc_h264_transform_8x8(param->bDirect8x8Inference)) {
4015         DEBUG_PRINT_ERROR("WARNING: Request for setting Transform8x8 failed");
4016         return false;
4017     }
4018 
4019     return true;
4020 }
4021 
venc_set_operatingrate(OMX_U32 rate)4022 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
4023     struct v4l2_control control;
4024 
4025     control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
4026     control.value = rate;
4027 
4028     if (rate > INT_MAX)
4029         control.value = INT_MAX;
4030 
4031     DEBUG_PRINT_LOW("venc_set_operating_rate: %u fps", rate >> 16);
4032     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%u", control.id, control.value);
4033 
4034     if (!strncmp(venc_handle->m_platform, "bengal", 6) &&
4035         (rate >> 16) > 30 && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
4036         venc_handle->m_sParamAVC.eProfile ==
4037             (OMX_VIDEO_AVCPROFILETYPE)QOMX_VIDEO_AVCProfileHigh &&
4038         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >= 1920 * 1080)) {
4039         if (!reconfigure_avc_param(&venc_handle->m_sParamAVC)) {
4040             DEBUG_PRINT_ERROR("reconfigure avc param fails");
4041         }
4042     }
4043 
4044     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4045         hw_overload = errno == EBUSY;
4046         DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
4047                 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
4048         return false;
4049     }
4050 
4051     operating_rate = rate >> 16;
4052     DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  rate >> 16);
4053 
4054     return true;
4055 }
4056 
venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO * roiInfo)4057 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo)
4058 {
4059     struct roidata roi;
4060 
4061     if (!m_roi_enabled) {
4062         DEBUG_PRINT_ERROR("ROI info not enabled");
4063         return false;
4064     }
4065 
4066     if (!roiInfo) {
4067         DEBUG_PRINT_ERROR("No ROI info present");
4068         return false;
4069     }
4070     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
4071     m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4072         DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %d codec", (OMX_U32) m_sVenc_cfg.codectype);
4073         return false;
4074     }
4075 
4076     memset(&roi, 0, sizeof(struct roidata));
4077 
4078     roi.info.nRoiMBInfoCount = roiInfo->nRoiMBInfoCount;
4079     roi.info.nTimeStamp = roiInfo->nTimeStamp;
4080     memcpy(roi.info.pRoiMBInfo, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoCount);
4081 
4082     roi.dirty = true;
4083 
4084     pthread_mutex_lock(&m_roilock);
4085     DEBUG_PRINT_LOW("list add roidata with timestamp %lld us.", roi.info.nTimeStamp);
4086     m_roilist.push_back(roi);
4087     pthread_mutex_unlock(&m_roilock);
4088 
4089     return true;
4090 }
4091 
venc_set_blur_resolution(OMX_QTI_VIDEO_CONFIG_BLURINFO * blurInfo)4092 bool venc_dev::venc_set_blur_resolution(OMX_QTI_VIDEO_CONFIG_BLURINFO *blurInfo)
4093 {
4094     struct v4l2_control ctrl;
4095 
4096     ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS;
4097     ctrl.value = blurInfo->nBlurInfo;
4098 
4099     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl)) {
4100         DEBUG_PRINT_ERROR("Failed to set blur resoltion");
4101         return false;
4102     }
4103 
4104     return true;
4105 }
4106 
venc_h264_transform_8x8(OMX_BOOL enable)4107 bool venc_dev::venc_h264_transform_8x8(OMX_BOOL enable)
4108 {
4109     struct v4l2_control control;
4110 
4111     control.id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
4112     if (enable)
4113         control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4114     else
4115         control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
4116 
4117     DEBUG_PRINT_LOW("Set h264_transform_8x8 mode: %d", control.value);
4118     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4119         DEBUG_PRINT_ERROR("set control: H264 transform 8x8 failed");
4120         return false;
4121     }
4122 
4123     return true;
4124 }
4125 
venc_get_temporal_layer_caps(OMX_U32 * nMaxLayers,OMX_U32 * nMaxBLayers,OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE * eSupportedPattern)4126 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
4127         OMX_U32 *nMaxBLayers, OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE *eSupportedPattern) {
4128 
4129     (void) nMaxBLayers;
4130     struct v4l2_queryctrl query_ctrl;
4131 
4132     if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC || m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4133         *eSupportedPattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4134     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4135         *eSupportedPattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4136     } else {
4137         *eSupportedPattern = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
4138     }
4139 
4140     query_ctrl.id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER;
4141 
4142     DEBUG_PRINT_LOW("TemporalLayer: Querying P layer caps");
4143     if (ioctl(m_nDriver_fd, VIDIOC_QUERYCTRL, &query_ctrl)) {
4144         DEBUG_PRINT_ERROR("TemporalLayer: Query control P layer caps failed");
4145         return false;
4146     }
4147 
4148     //Return +1 as driver works on num max enhancement layers and OMX on num layers
4149     *nMaxLayers = query_ctrl.maximum + 1;
4150 
4151     return true;
4152 }
4153 
venc_set_bitrate_ratios()4154 OMX_ERRORTYPE venc_dev::venc_set_bitrate_ratios()
4155 {
4156     struct v4l2_control ctrl;
4157     int rc = 0;
4158     OMX_U32 ids[] = {
4159         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR,
4160         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR,
4161         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR,
4162         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR,
4163         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR,
4164         V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR,
4165     };
4166 
4167     DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio");
4168 
4169     // Set all bitrate ratios to kernel. If client hasn't set bitrate ratio
4170     // for a layer, 0 is passed on to kernel.
4171     for (OMX_U32 i = 0; i < (OMX_U32)(sizeof(ids)/sizeof(ids[0])); ++i) {
4172         ctrl.id = ids[i];
4173         ctrl.value = temporal_layers_config.nTemporalLayerBitrateRatio[i];
4174 
4175         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl);
4176         if (rc) {
4177             DEBUG_PRINT_ERROR("Failed to set layerwise bitrate ratio. Id= %u, Value= %u, error %d",
4178                               ctrl.id, ctrl.value, rc);
4179             return OMX_ErrorUnsupportedSetting;
4180         }
4181         DEBUG_PRINT_LOW("Layerwise bitrate configured successfully for layer: %u, bitrate: %u",
4182                         i, temporal_layers_config.nTemporalLayerBitrateRatio[i]);
4183     }
4184 	return OMX_ErrorNone;
4185 }
4186 
venc_get_hevc_profile(OMX_U32 * profile)4187 bool venc_dev::venc_get_hevc_profile(OMX_U32* profile)
4188 {
4189     if (profile == nullptr) return false;
4190 
4191     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4192         if(profile_level_converter::convert_v4l2_profile_to_omx(V4L2_PIX_FMT_HEVC, codec_profile.profile, (int*)profile)) {
4193             return true;
4194         } else return false;
4195     } else return false;
4196 }
4197 
venc_get_profile_level(OMX_U32 * eProfile,OMX_U32 * eLevel)4198 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
4199 {
4200     bool status = true;
4201 
4202     if (eProfile == NULL || eLevel == NULL) {
4203         return false;
4204     }
4205 
4206     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
4207         switch (codec_profile.profile) {
4208             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
4209                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
4210                 break;
4211             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
4212                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
4213                 break;
4214             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
4215                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
4216                 break;
4217             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4218                 *eProfile = OMX_VIDEO_AVCProfileMain;
4219                 break;
4220             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4221                 *eProfile = OMX_VIDEO_AVCProfileHigh;
4222                 break;
4223             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4224                 *eProfile = OMX_VIDEO_AVCProfileExtended;
4225                 break;
4226             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4227                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
4228                 break;
4229             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4230                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
4231                 break;
4232             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4233                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
4234                 break;
4235             default:
4236                 *eProfile = OMX_VIDEO_AVCProfileMax;
4237                 status = false;
4238                 break;
4239         }
4240 
4241         if (!status) {
4242             return status;
4243         }
4244 
4245         switch (profile_level.level) {
4246             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
4247                 *eLevel = OMX_VIDEO_AVCLevel1;
4248                 break;
4249             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
4250                 *eLevel = OMX_VIDEO_AVCLevel1b;
4251                 break;
4252             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
4253                 *eLevel = OMX_VIDEO_AVCLevel11;
4254                 break;
4255             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
4256                 *eLevel = OMX_VIDEO_AVCLevel12;
4257                 break;
4258             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
4259                 *eLevel = OMX_VIDEO_AVCLevel13;
4260                 break;
4261             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4262                 *eLevel = OMX_VIDEO_AVCLevel2;
4263                 break;
4264             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4265                 *eLevel = OMX_VIDEO_AVCLevel21;
4266                 break;
4267             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4268                 *eLevel = OMX_VIDEO_AVCLevel22;
4269                 break;
4270             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4271                 *eLevel = OMX_VIDEO_AVCLevel3;
4272                 break;
4273             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4274                 *eLevel = OMX_VIDEO_AVCLevel31;
4275                 break;
4276             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4277                 *eLevel = OMX_VIDEO_AVCLevel32;
4278                 break;
4279             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4280                 *eLevel = OMX_VIDEO_AVCLevel4;
4281                 break;
4282             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4283                 *eLevel = OMX_VIDEO_AVCLevel41;
4284                 break;
4285             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4286                 *eLevel = OMX_VIDEO_AVCLevel42;
4287                 break;
4288             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4289                 *eLevel = OMX_VIDEO_AVCLevel5;
4290                 break;
4291             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4292                 *eLevel = OMX_VIDEO_AVCLevel51;
4293                 break;
4294             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4295                 *eLevel = OMX_VIDEO_AVCLevel52;
4296                 break;
4297             default :
4298                 *eLevel = OMX_VIDEO_AVCLevelMax;
4299                 status = false;
4300                 break;
4301         }
4302     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
4303         switch (codec_profile.profile) {
4304             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
4305                 *eProfile = OMX_VIDEO_VP8ProfileMain;
4306                 break;
4307             default:
4308                 *eProfile = OMX_VIDEO_VP8ProfileMax;
4309                 status = false;
4310                 break;
4311         }
4312         if (!status) {
4313             return status;
4314         }
4315 
4316         switch (profile_level.level) {
4317             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
4318                 *eLevel = OMX_VIDEO_VP8Level_Version0;
4319                 break;
4320             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
4321                 *eLevel = OMX_VIDEO_VP8Level_Version1;
4322                 break;
4323             default:
4324                 *eLevel = OMX_VIDEO_VP8LevelMax;
4325                 status = false;
4326                 break;
4327         }
4328     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
4329         switch (codec_profile.profile) {
4330             case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
4331                 *eProfile = OMX_VIDEO_HEVCProfileMain;
4332                 break;
4333             case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
4334                 *eProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
4335                 break;
4336             case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
4337                 *eProfile = OMX_VIDEO_HEVCProfileMainStill;
4338                 break;
4339             default:
4340                 *eProfile = OMX_VIDEO_HEVCProfileMax;
4341                 status = false;
4342                 break;
4343         }
4344         if (!status) {
4345             return status;
4346         }
4347 
4348         switch (profile_level.level) {
4349             case V4L2_MPEG_VIDEO_HEVC_LEVEL_1:
4350                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4351                                      OMX_VIDEO_HEVCMainTierLevel1:OMX_VIDEO_HEVCHighTierLevel1;
4352                 break;
4353             case V4L2_MPEG_VIDEO_HEVC_LEVEL_2:
4354                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4355                                      OMX_VIDEO_HEVCMainTierLevel2:OMX_VIDEO_HEVCHighTierLevel2;
4356                 break;
4357             case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1:
4358                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4359                                      OMX_VIDEO_HEVCMainTierLevel21:OMX_VIDEO_HEVCHighTierLevel21;
4360                 break;
4361             case V4L2_MPEG_VIDEO_HEVC_LEVEL_3:
4362                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4363                                      OMX_VIDEO_HEVCMainTierLevel3:OMX_VIDEO_HEVCHighTierLevel3;
4364                 break;
4365             case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1:
4366                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4367                                      OMX_VIDEO_HEVCMainTierLevel31:OMX_VIDEO_HEVCHighTierLevel31;
4368                 break;
4369             case V4L2_MPEG_VIDEO_HEVC_LEVEL_4:
4370                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4371                                      OMX_VIDEO_HEVCMainTierLevel4:OMX_VIDEO_HEVCHighTierLevel4;
4372                 break;
4373             case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1:
4374                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4375                                      OMX_VIDEO_HEVCMainTierLevel41:OMX_VIDEO_HEVCHighTierLevel41;
4376                 break;
4377             case V4L2_MPEG_VIDEO_HEVC_LEVEL_5:
4378                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4379                                      OMX_VIDEO_HEVCMainTierLevel5:OMX_VIDEO_HEVCHighTierLevel5;
4380                 break;
4381             case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1:
4382                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4383                                      OMX_VIDEO_HEVCMainTierLevel51:OMX_VIDEO_HEVCHighTierLevel51;
4384                 break;
4385             case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2:
4386                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4387                                      OMX_VIDEO_HEVCMainTierLevel52:OMX_VIDEO_HEVCHighTierLevel52;
4388                 break;
4389             case V4L2_MPEG_VIDEO_HEVC_LEVEL_6:
4390                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4391                                      OMX_VIDEO_HEVCMainTierLevel6:OMX_VIDEO_HEVCHighTierLevel6;
4392                 break;
4393             case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1:
4394                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4395                                      OMX_VIDEO_HEVCMainTierLevel61:OMX_VIDEO_HEVCHighTierLevel61;
4396                 break;
4397             case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2:
4398                 *eLevel = (profile_level.tier == V4L2_MPEG_VIDEO_HEVC_TIER_MAIN)?
4399                                      OMX_VIDEO_HEVCMainTierLevel62:OMX_VIDEO_HEVCHighTierLevel62;
4400                 break;
4401             default:
4402                 *eLevel = OMX_VIDEO_HEVCHighTiermax;
4403                 status = false;
4404                 break;
4405         }
4406     }
4407 
4408     return status;
4409 }
4410 
venc_set_nal_size(OMX_VIDEO_CONFIG_NALSIZE * nalSizeInfo)4411 bool venc_dev::venc_set_nal_size (OMX_VIDEO_CONFIG_NALSIZE *nalSizeInfo) {
4412     struct v4l2_control sControl;
4413 
4414     DEBUG_PRINT_HIGH("set video stream format - nal size - %u", nalSizeInfo->nNaluBytes);
4415 
4416     sControl.id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD;
4417     switch (nalSizeInfo->nNaluBytes) {
4418         case 0:
4419             sControl.value = V4L2_MPEG_VIDEO_HEVC_SIZE_0;
4420             break;
4421         case 4:
4422             sControl.value = V4L2_MPEG_VIDEO_HEVC_SIZE_4;
4423             break;
4424         default:
4425             return false;
4426     }
4427 
4428     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sControl)) {
4429         DEBUG_PRINT_ERROR("set control: video stream format failed - %u",
4430                 (unsigned int)nalSizeInfo->nNaluBytes);
4431         return false;
4432     }
4433     return true;
4434 }
4435 
venc_superframe_enable(private_handle_t * handle)4436 bool venc_dev::venc_superframe_enable(private_handle_t *handle)
4437 {
4438     struct v4l2_control ctrl;
4439     OMX_U32 frame_size;
4440     unsigned long color_format;
4441 
4442     ctrl.id = V4L2_CID_MPEG_VIDC_SUPERFRAME;
4443     color_format = get_media_colorformat(m_sVenc_cfg.inputformat);
4444     frame_size = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
4445 
4446     /*
4447     * disable superframe if handle->size is not multiple of
4448     * frame_size or if it is a single frame.
4449     */
4450     if (handle->size % frame_size || handle->size == frame_size) {
4451         DEBUG_PRINT_ERROR("Invalid superframe handle size %d for frame size %d",
4452             handle->size, frame_size);
4453         return false;
4454     }
4455     ctrl.value = handle->size / frame_size;
4456     DEBUG_PRINT_HIGH("venc_superframe_enable: %d", ctrl.value);
4457     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl)) {
4458         DEBUG_PRINT_ERROR("Failed to enable superframe, errno %d", errno);
4459         return false;
4460     }
4461     return true;
4462 }
4463 
venc_cvp_enable(private_handle_t * handle)4464 bool venc_dev::venc_cvp_enable(private_handle_t *handle)
4465 {
4466     cvpMetadata.size = 0;
4467     if (temporal_layers_config.nMaxLayers > 1) {
4468         DEBUG_PRINT_INFO("venc_cvp_enable: disabling CVP as max layers %u", temporal_layers_config.nMaxLayers);
4469         return true;
4470     }
4471     if (getMetaData(handle, GET_CVP_METADATA, &cvpMetadata) == 0) {
4472         if (cvpMetadata.size == CVP_METADATA_SIZE) {
4473             struct v4l2_control control;
4474             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
4475             control.value = EXTRADATA_ENC_INPUT_CVP;
4476             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
4477                 DEBUG_PRINT_ERROR("ERROR: Setting CVP metadata extradata control failed");
4478                 return false;
4479             }
4480             m_cvp_meta_enabled = true;
4481             m_cvp_first_metadata = true;
4482             DEBUG_PRINT_HIGH("CVP metadata enabled");
4483             if (!venc_set_cvp_skipratio_controls())
4484                 return false;
4485         } else {
4486             DEBUG_PRINT_ERROR("ERROR: External CVP mode disabled for this session and continue!");
4487             setMetaData(handle, SET_CVP_METADATA, 0);
4488         }
4489     } else {
4490         DEBUG_PRINT_INFO("venc_cvp_enable: cvp metadata not available");
4491     }
4492     return true;
4493 }
4494 
venc_set_cvp_skipratio_controls()4495 bool venc_dev::venc_set_cvp_skipratio_controls()
4496 {
4497     struct v4l2_control ctrl;
4498 
4499     if (!cvpMetadata.cvp_frame_rate || !cvpMetadata.capture_frame_rate) {
4500         DEBUG_PRINT_ERROR("ERROR: Invalid cvp frame rate received");
4501         return true;
4502     }
4503     DEBUG_PRINT_HIGH("cvpMetadata: frame_rate %u capture rate %u", cvpMetadata.cvp_frame_rate, cvpMetadata.capture_frame_rate);
4504 
4505     ctrl.id = V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE;
4506     ctrl.value = cvpMetadata.capture_frame_rate;
4507     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl)) {
4508         DEBUG_PRINT_ERROR("ERROR: Setting capture frame rate control failed");
4509         return false;
4510     }
4511 
4512     ctrl.id = V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE;
4513     ctrl.value = cvpMetadata.cvp_frame_rate;
4514     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl)) {
4515         DEBUG_PRINT_ERROR("ERROR: Setting cvp frame rate control failed");
4516         return false;
4517     }
4518     return true;
4519 }
4520 
venc_get_cvp_metadata(private_handle_t * handle,struct v4l2_buffer * buf)4521 bool venc_dev::venc_get_cvp_metadata(private_handle_t *handle, struct v4l2_buffer *buf)
4522 {
4523     if (!m_cvp_meta_enabled)
4524         return true;
4525 
4526     unsigned int capture_rate = cvpMetadata.capture_frame_rate;
4527     unsigned int cvp_rate = cvpMetadata.cvp_frame_rate;
4528 
4529     buf->flags &= ~V4L2_BUF_FLAG_CVPMETADATA_SKIP;
4530     cvpMetadata.size = 0;
4531     if (getMetaData(handle, GET_CVP_METADATA, &cvpMetadata) == 0) {
4532         setMetaData(handle, SET_CVP_METADATA, 0);
4533         if (cvpMetadata.size != CVP_METADATA_SIZE) {
4534             DEBUG_PRINT_ERROR("ERROR: Invalid CVP metadata size %d",
4535                 cvpMetadata.size);
4536             cvpMetadata.size = 0;
4537             /* If camera sends metadata of size not matching to CVP_METADATA_SIZE,
4538                it is considered as an error case. So, do not add skip flag */
4539             return false;
4540         }
4541         DEBUG_PRINT_LOW("CVP metadata size %d", cvpMetadata.size);
4542         if (m_debug.cvp_log) {
4543             venc_cvp_log_buffers("CVP", cvpMetadata.size, cvpMetadata.payload);
4544         }
4545     } else {
4546         DEBUG_PRINT_ERROR("ERROR: CVP metadata not available");
4547         return false;
4548     }
4549 
4550     if (m_cvp_first_metadata) {
4551         m_cvp_first_metadata = false;
4552     } else if (cvpMetadata.flags & CVP_METADATA_FLAG_REPEAT) {
4553         buf->flags |= V4L2_BUF_FLAG_CVPMETADATA_SKIP;
4554         DEBUG_PRINT_LOW("venc_empty_buf: V4L2_BUF_FLAG_CVPMETADATA_SKIP is set");
4555     }
4556 
4557     if ((cvpMetadata.capture_frame_rate != capture_rate) ||
4558         (cvpMetadata.cvp_frame_rate != cvp_rate)) {
4559         if(!venc_set_cvp_skipratio_controls())
4560             return false;
4561     }
4562     return true;
4563 }
4564 
venc_config_bitrate(OMX_VIDEO_CONFIG_BITRATETYPE * bit_rate)4565 bool venc_dev::venc_config_bitrate(OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate)
4566 {
4567     OMX_U32 bitrate = bit_rate->nEncodeBitrate;
4568     if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
4569         // If quality boost is eligible, also increase bitrate by 15% in dynamic change case
4570         if (mQualityBoostEligible && bitrate < VENC_QUALITY_BOOST_BITRATE_THRESHOLD) {
4571             bitrate += bitrate * 15 / 100;
4572         }
4573         if (venc_set_target_bitrate(bitrate) == false) {
4574             DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
4575             return false;
4576         }
4577     } else {
4578         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
4579         return false;
4580     }
4581     return true;
4582 }
4583 
venc_config_framerate(OMX_CONFIG_FRAMERATETYPE * frame_rate)4584 bool venc_dev::venc_config_framerate(OMX_CONFIG_FRAMERATETYPE *frame_rate)
4585 {
4586     if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
4587         if (venc_set_encode_framerate(frame_rate->xEncodeFramerate) == false) {
4588             DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
4589             return false;
4590         }
4591     } else {
4592         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
4593         return false;
4594     }
4595     return true;
4596 }
4597 
venc_config_intravoprefresh(OMX_CONFIG_INTRAREFRESHVOPTYPE * intra_vop_refresh)4598 bool venc_dev::venc_config_intravoprefresh(OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh)
4599 {
4600     if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
4601         if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
4602             DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
4603             return false;
4604         }
4605     } else {
4606         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
4607         return false;
4608     }
4609 
4610     return true;
4611 }
4612 
venc_config_markLTR(OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE * markltr)4613 bool venc_dev::venc_config_markLTR(OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE *markltr)
4614 {
4615     if (markltr->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
4616         if(venc_set_markltr(markltr->nID) == false) {
4617             DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
4618             return false;
4619         }
4620     }  else {
4621         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
4622         return false;
4623     }
4624     return true;
4625 }
4626 
venc_config_useLTR(OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE * useltr)4627 bool venc_dev::venc_config_useLTR(OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE *useltr)
4628 {
4629     if (useltr->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
4630         if(venc_set_useltr(useltr->nID) == false) {
4631             DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
4632             return false;
4633         }
4634     } else {
4635         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
4636         return false;
4637     }
4638     return true;
4639 }
4640 
venc_config_qp(OMX_SKYPE_VIDEO_CONFIG_QP * configqp)4641 bool venc_dev::venc_config_qp(OMX_SKYPE_VIDEO_CONFIG_QP *configqp)
4642 {
4643     if (venc_set_qp(configqp->nQP,
4644                     configqp->nQP,
4645                     configqp->nQP,
4646                     ENABLE_I_QP | ENABLE_P_QP | ENABLE_B_QP ) == false) {
4647         DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
4648         return false;
4649     }
4650     return true;
4651 }
4652 
venc_config_vp8refframe(OMX_VIDEO_VP8REFERENCEFRAMETYPE * vp8refframe)4653 bool venc_dev::venc_config_vp8refframe(OMX_VIDEO_VP8REFERENCEFRAMETYPE *vp8refframe)
4654 {
4655     if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
4656             (vp8refframe->bUseGoldenFrame)) {
4657         if(venc_set_useltr(0x1) == false) {
4658             DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
4659             return false;
4660         }
4661     } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
4662             (vp8refframe->bGoldenFrameRefresh)) {
4663         if(venc_set_markltr(0x1) == false) {
4664             DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
4665             return false;
4666         }
4667     } else {
4668         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
4669         return false;
4670     }
4671     return true;
4672 }
4673 
4674 #ifdef _ANDROID_ICS_
venc_set_meta_mode(bool mode)4675 bool venc_dev::venc_set_meta_mode(bool mode)
4676 {
4677     metadatamode = mode;
4678     return true;
4679 }
4680 #endif
4681 
venc_is_video_session_supported(unsigned long width,unsigned long height)4682 bool venc_dev::venc_is_video_session_supported(unsigned long width,
4683         unsigned long height)
4684 {
4685     if ((width * height < capability.min_width *  capability.min_height) ||
4686             (width * height > capability.max_width *  capability.max_height)) {
4687         DEBUG_PRINT_ERROR(
4688                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
4689                 width, height, capability.min_width, capability.min_height,
4690                 capability.max_width, capability.max_height);
4691         return false;
4692     }
4693 
4694     DEBUG_PRINT_LOW("video session supported");
4695     return true;
4696 }
4697 
BatchInfo()4698 venc_dev::BatchInfo::BatchInfo()
4699     : mNumPending(0) {
4700     pthread_mutex_init(&mLock, NULL);
4701     for (int i = 0; i < kMaxBufs; ++i) {
4702         mBufMap[i] = kBufIDFree;
4703     }
4704 }
4705 
registerBuffer(int bufferId)4706 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
4707     pthread_mutex_lock(&mLock);
4708     int availId = 0;
4709     for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
4710     if (availId >= kMaxBufs) {
4711         DEBUG_PRINT_ERROR("Failed to find free entry !");
4712         pthread_mutex_unlock(&mLock);
4713         return -1;
4714     }
4715     mBufMap[availId] = bufferId;
4716     mNumPending++;
4717     pthread_mutex_unlock(&mLock);
4718     return availId;
4719 }
4720 
retrieveBufferAt(int v4l2Id)4721 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
4722     pthread_mutex_lock(&mLock);
4723     if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
4724         DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
4725         pthread_mutex_unlock(&mLock);
4726         return -1;
4727     }
4728     if (mBufMap[v4l2Id] == kBufIDFree) {
4729         DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
4730         pthread_mutex_unlock(&mLock);
4731         return -1;
4732     }
4733     int bufferId = mBufMap[v4l2Id];
4734     mBufMap[v4l2Id] = kBufIDFree;
4735     mNumPending--;
4736     pthread_mutex_unlock(&mLock);
4737     return bufferId;
4738 }
4739 
isPending(int bufferId)4740 bool venc_dev::BatchInfo::isPending(int bufferId) {
4741     pthread_mutex_lock(&mLock);
4742     int existsId = 0;
4743     for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
4744     pthread_mutex_unlock(&mLock);
4745     return existsId < kMaxBufs;
4746 }
4747 
venc_set_hdr_info(const MasteringDisplay & mastering_disp_info,const ContentLightLevel & content_light_level_info)4748 bool venc_dev::venc_set_hdr_info(const MasteringDisplay& mastering_disp_info,
4749                             const ContentLightLevel& content_light_level_info)
4750 {
4751     struct v4l2_control ctrl = {0, 0};
4752     const unsigned int hdr_info[] = {
4753         MSM_VIDC_RGB_PRIMARY_00,
4754         MSM_VIDC_RGB_PRIMARY_01,
4755         MSM_VIDC_RGB_PRIMARY_10,
4756         MSM_VIDC_RGB_PRIMARY_11,
4757         MSM_VIDC_RGB_PRIMARY_20,
4758         MSM_VIDC_RGB_PRIMARY_21,
4759         MSM_VIDC_WHITEPOINT_X,
4760         MSM_VIDC_WHITEPOINT_Y,
4761         MSM_VIDC_MAX_DISP_LUM,
4762         MSM_VIDC_MIN_DISP_LUM,
4763         MSM_VIDC_RGB_MAX_CLL,
4764         MSM_VIDC_RGB_MAX_FLL
4765     };
4766 
4767     unsigned int values[] = {
4768         mastering_disp_info.primaries.rgbPrimaries[0][0],
4769         mastering_disp_info.primaries.rgbPrimaries[0][1],
4770         mastering_disp_info.primaries.rgbPrimaries[1][0],
4771         mastering_disp_info.primaries.rgbPrimaries[1][1],
4772         mastering_disp_info.primaries.rgbPrimaries[2][0],
4773         mastering_disp_info.primaries.rgbPrimaries[2][1],
4774         mastering_disp_info.primaries.whitePoint[0],
4775         mastering_disp_info.primaries.whitePoint[1],
4776         // maxDisplayLuminance is in cd/m^2 scale. But the standard requires this field
4777         // to be in 0.0001 cd/m^2 scale. So, multiply with LUMINANCE_MULTIPLICATION_FACTOR
4778         // and give to be driver
4779         mastering_disp_info.maxDisplayLuminance * LUMINANCE_MULTIPLICATION_FACTOR,
4780         mastering_disp_info.minDisplayLuminance,
4781         content_light_level_info.maxContentLightLevel,
4782         content_light_level_info.minPicAverageLightLevel
4783     };
4784 
4785     ctrl.id = V4L2_CID_MPEG_VIDC_VENC_HDR_INFO;
4786 
4787     for (unsigned int i = 0; i < (sizeof(hdr_info)/sizeof(hdr_info[0])); i++) {
4788         ctrl.value = (unsigned int) ((values[i] & 0xFFFFFFF ) | (hdr_info[i] << 28));
4789         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &ctrl)) {
4790             DEBUG_PRINT_ERROR("VIDIOC_S_CTRL failed for HDR Info : (%u) value %#X : %#X",
4791                               i, hdr_info[i], values[i]);
4792             return false;
4793         }
4794     }
4795 
4796     return true;
4797 }
4798 
4799 /*=================================================================================
4800  * Function:   venc_set_roi_region_qp_info
4801  * @brief      set the config of OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO and store
4802  *             the info in the list
4803  * Parameters:
4804  * @param      OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO *roiRegionInfo:
4805  *             the config to be set
4806  * Return value:
4807  *             bool: return true if the config is set successfully
4808 *==================================================================================*/
venc_set_roi_region_qp_info(OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO * roiRegionInfo)4809 bool venc_dev::venc_set_roi_region_qp_info(OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO *roiRegionInfo)
4810 {
4811     if (!m_roi_enabled || m_roi_type == ROI_NONE) {
4812         DEBUG_PRINT_ERROR("ROI-Region: roi info not enabled (%d) or unknown roi type (%u)",
4813             m_roi_enabled, m_roi_type);
4814         return false;
4815     }
4816     if (!roiRegionInfo) {
4817         DEBUG_PRINT_ERROR("ROI-Region: no region info present");
4818         return false;
4819     }
4820     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
4821             m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
4822         DEBUG_PRINT_ERROR("ROI-Region: is not supported for %d codec",
4823                 (OMX_U32) m_sVenc_cfg.codectype);
4824         return false;
4825     }
4826 
4827     pthread_mutex_lock(&m_roilock);
4828     DEBUG_PRINT_LOW("ROI-Region: add region with timestamp %lld us.", roiRegionInfo->nTimeStamp);
4829     mRoiRegionList.push_back(*roiRegionInfo);
4830     pthread_mutex_unlock(&m_roilock);
4831     return true;
4832 }
4833 
4834 /*=================================================================================
4835  * Function:   append_extradata_roi_region_qp_info
4836  * @brief      fill the roi info in the extradata of input Buffer
4837  * Parameters:
4838  * @param      OMX_OTHER_EXTRADATATYPE *data: the address of the extradata buffer
4839  *             OMX_TICKS timestamp:  the timestamp of the input Buffer
4840  *             OMX_U32: the available size of the extradata buffer
4841  * Return value:
4842  *             OMX_U32: the filled size
4843 *==================================================================================*/
append_extradata_roi_region_qp_info(OMX_OTHER_EXTRADATATYPE * data,OMX_TICKS timestamp,OMX_U32 freeSize)4844 OMX_U32 venc_dev::append_extradata_roi_region_qp_info(OMX_OTHER_EXTRADATATYPE *data,
4845         OMX_TICKS timestamp, OMX_U32 freeSize)
4846 {
4847     bool found = false;
4848     pthread_mutex_lock(&m_roilock);
4849     if (mRoiRegionList.size() == 0) {
4850         pthread_mutex_unlock(&m_roilock);
4851         return 0;
4852     }
4853     std::list<OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO>::iterator it =
4854             mRoiRegionList.begin();
4855     while (it != mRoiRegionList.end()) {
4856         if (it->nTimeStamp < timestamp) {
4857             it = mRoiRegionList.erase(it);
4858             continue;
4859         } else if (it->nTimeStamp == timestamp) {
4860             found = true;
4861             break;
4862         }
4863         it++;
4864     }
4865     pthread_mutex_unlock(&m_roilock);
4866     if (!found) {
4867         DEBUG_PRINT_LOW("ROI-Region: no region roi data was found");
4868         return 0;
4869     }
4870     OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO regionInfo = *it;
4871     bool isHevc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC ? true:false;
4872     OMX_U32 height = m_sVenc_cfg.dvs_height;
4873     OMX_U32 width = m_sVenc_cfg.dvs_width;
4874     OMX_U32 mbAlign = isHevc ? 32 : 16;
4875     OMX_U8 mbBit = isHevc ? 5 : 4;
4876     OMX_U32 mbRow = ALIGN(width, mbAlign) / mbAlign;
4877     OMX_U32 mbCol = ALIGN(height, mbAlign) / mbAlign;
4878     OMX_U32 numBytes, mbLeft, mbTop, mbRight, mbBottom = 0;
4879     OMX_S8 deltaQP = 0;
4880     DEBUG_PRINT_LOW("ROI-Region: clip(%ux%u: %s), mb(%ux%u), region(num:%u, ts:%lld)",
4881             width, height, isHevc ? "hevc" : "avc", mbRow, mbCol, regionInfo.nRegionNum,
4882             regionInfo.nTimeStamp);
4883 
4884     if (m_roi_type == ROI_2BYTE) {
4885         OMX_U32 mbRowAligned = ALIGN(mbRow, 8);
4886         numBytes = mbRowAligned * mbCol * 2;
4887         OMX_U32 numBytesAligned = ALIGN(numBytes, 4);
4888 
4889         data->nDataSize = ALIGN(sizeof(struct msm_vidc_roi_deltaqp_payload), 256)
4890                             + numBytesAligned;
4891         data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + data->nDataSize, 4);
4892         if (data->nSize > freeSize) {
4893             DEBUG_PRINT_ERROR("ROI-Region: Buffer size(%u) is less than ROI extradata size(%u)",
4894                      freeSize, data->nSize);
4895             data->nDataSize = 0;
4896             data->nSize = 0;
4897             return 0;
4898         }
4899 
4900         data->nVersion.nVersion = OMX_SPEC_VERSION;
4901         data->nPortIndex = 0;
4902         data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
4903         struct msm_vidc_roi_deltaqp_payload *roiData =
4904                 (struct msm_vidc_roi_deltaqp_payload *)(data->data);
4905         roiData->b_roi_info = true;
4906         roiData->mbi_info_size = numBytesAligned;
4907         roiData->data[0] = (unsigned int)(ALIGN(&roiData->data[1], 256)
4908                 - (unsigned long)roiData->data);
4909         OMX_U16* exDataBuf = (OMX_U16*)((OMX_U8*)roiData->data + roiData->data[0]);
4910         OMX_U32 mb = 0;
4911         OMX_U16 *pData = NULL;
4912 
4913         for (OMX_U8 i = 0; i < regionInfo.nRegionNum; i++) {
4914             mbLeft = regionInfo.nRegions[i].nLeft >> mbBit;
4915             mbTop = regionInfo.nRegions[i].nTop >> mbBit;
4916             mbRight = regionInfo.nRegions[i].nRight >> mbBit;
4917             mbBottom = regionInfo.nRegions[i].nBottom >> mbBit;
4918             deltaQP = regionInfo.nRegions[i].nDeltaQP;
4919             if (mbLeft >= mbRow || mbRight >= mbRow
4920                     || mbTop >= mbCol || mbBottom >= mbCol) {
4921                 continue;
4922             }
4923             for (OMX_U32 row = mbTop; row <= mbBottom; row++) {
4924                 for (OMX_U32 col = mbLeft; col <= mbRight; col++) {
4925                     mb = row * mbRowAligned + col;
4926                     pData = exDataBuf + mb;
4927                    *pData = (1 << 11) | ((deltaQP & 0x3F) << 4);
4928                 }
4929             }
4930         }
4931         DEBUG_PRINT_LOW("ROI-Region(2Byte): set roi: raw size: %u", numBytesAligned);
4932     } else if (m_roi_type == ROI_2BIT) {
4933         numBytes = (mbRow * mbCol * 2 + 7) >> 3;
4934         data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload) + numBytes;
4935         data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + data->nDataSize, 4);
4936 
4937         if (data->nSize > freeSize) {
4938             DEBUG_PRINT_ERROR("ROI-Region: Buffer size(%u) is less than ROI extradata size(%u)",
4939                     freeSize, data->nSize);
4940             data->nDataSize = 0;
4941             data->nSize = 0;
4942             return 0;
4943         }
4944 
4945         data->nVersion.nVersion = OMX_SPEC_VERSION;
4946         data->nPortIndex = 0;
4947         data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
4948         struct msm_vidc_roi_qp_payload *roiData =
4949                 (struct msm_vidc_roi_qp_payload *)(data->data);
4950         roiData->b_roi_info = true;
4951         roiData->mbi_info_size = numBytes;
4952         roiData->lower_qp_offset = 0;
4953         roiData->upper_qp_offset = 0;
4954         OMX_U8 flag = 0x1;
4955         OMX_U32 mb, mb_byte = 0;
4956         OMX_U8 mb_bit = 0;
4957         OMX_U8 *pData = NULL;
4958 
4959         for (OMX_U8 i = 0; i < regionInfo.nRegionNum; i++) {
4960             mbLeft = regionInfo.nRegions[i].nLeft >> mbBit;
4961             mbTop = regionInfo.nRegions[i].nTop >> mbBit;
4962             mbRight = regionInfo.nRegions[i].nRight >> mbBit;
4963             mbBottom = regionInfo.nRegions[i].nBottom >> mbBit;
4964             deltaQP = regionInfo.nRegions[i].nDeltaQP;
4965             if (mbLeft >= mbRow || mbRight >= mbRow
4966                     || mbTop >= mbCol || mbBottom >= mbCol
4967                     || deltaQP == 0) {
4968                 continue;
4969             }
4970             // choose the minimum absolute value for lower and upper offset
4971             if (deltaQP < 0) {
4972                 if (roiData->lower_qp_offset == 0) {
4973                     roiData->lower_qp_offset = deltaQP;
4974                 } else if (roiData->lower_qp_offset < deltaQP) {
4975                     roiData->lower_qp_offset = deltaQP;
4976                 }
4977                 flag = 0x1;
4978             } else {
4979                 if (roiData->upper_qp_offset == 0) {
4980                     roiData->upper_qp_offset = deltaQP;
4981                 } else if (roiData->upper_qp_offset > deltaQP) {
4982                     roiData->upper_qp_offset = deltaQP;
4983                 }
4984                 flag = 0x2;
4985             }
4986             for (OMX_U32 row = mbTop; row <= mbBottom; row++) {
4987                 for (OMX_U32 col = mbLeft; col <= mbRight; col++) {
4988                     mb = row * mbRow + col;
4989                     mb_byte = mb >> 2;
4990                     mb_bit = (3 - (mb & 0x3)) << 1;
4991                     pData = (OMX_U8 *)roiData->data + mb_byte;
4992                     *pData |= (flag << mb_bit);
4993                 }
4994             }
4995         }
4996         DEBUG_PRINT_LOW("ROI-Region(2Bit):set roi low:%d,up:%d", roiData->lower_qp_offset, roiData->upper_qp_offset);
4997     } else {
4998         DEBUG_PRINT_ERROR("Invalied roi type : %u", m_roi_type);
4999         return 0;
5000     }
5001     return data->nSize;
5002 }
5003 
venc_set_quality_boost(OMX_BOOL c2d_enable)5004 void venc_dev::venc_set_quality_boost(OMX_BOOL c2d_enable)
5005 {
5006     OMX_U32 initial_qp;
5007     OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE qp_range;
5008     OMX_QTI_VIDEO_CONFIG_BLURINFO blurinfo;
5009 
5010     // Conditions to enable encoder quality boost,
5011     // 1. Codec is AVC
5012     // 2. RCMode is VBR
5013     // 3. Input is RGBA/RGBA_UBWC (C2D enabled)
5014     // 4. width <= 960 and height <= 960
5015     // 5. width >= 400 and height >= 400
5016     // 6. FPS <= 30
5017     // 7. bitrate < 2Mbps
5018 
5019     if (mQualityBoostRequested && c2d_enable &&
5020         m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
5021         rate_ctrl.rcmode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
5022         m_sVenc_cfg.dvs_width <= 960 && m_sVenc_cfg.dvs_height <= 960 &&
5023         m_sVenc_cfg.dvs_width >= 400 && m_sVenc_cfg.dvs_height >= 400 &&
5024         (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den) <= 30 &&
5025         bitrate.target_bitrate < VENC_QUALITY_BOOST_BITRATE_THRESHOLD) {
5026         mQualityBoostEligible = true;
5027         DEBUG_PRINT_HIGH("Quality boost eligible encoder session");
5028     } else {
5029         return;
5030     }
5031 
5032     if (bitrate.target_bitrate <= 64000)
5033         venc_set_level(OMX_VIDEO_AVCLevel1);
5034 
5035     // Set below configurations to boost quality
5036     // 1. Increase bitrate by 15%
5037     bitrate.target_bitrate += bitrate.target_bitrate * 15 / 100;
5038     venc_set_target_bitrate(bitrate.target_bitrate);
5039 
5040     // 2. Set initial QP=30
5041     initial_qp = 30;
5042     venc_set_qp(initial_qp, initial_qp, initial_qp, 7);
5043 
5044     // 3. Set QP range [10,40]
5045     qp_range.minIQP = qp_range.minPQP = qp_range.minBQP = 10;
5046     qp_range.maxIQP = qp_range.maxPQP = qp_range.maxBQP = 40;
5047     venc_set_session_qp_range(&qp_range);
5048 
5049     // 4. Disable blur (both external and internal)
5050     blurinfo.nBlurInfo = 2;
5051     venc_set_blur_resolution(&blurinfo);
5052 
5053     // 5. Disable bitrate savings (CAC)
5054     venc_set_bitrate_savings_mode(0);
5055 }
5056