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 /*============================================================================
30                             O p e n M A X   w r a p p e r s
31                              O p e n  M A X   C o r e
32 
33   This module contains the implementation of the OpenMAX core & component.
34 
35 *//*========================================================================*/
36 
37 //////////////////////////////////////////////////////////////////////////////
38 //                             Include Files
39 //////////////////////////////////////////////////////////////////////////////
40 
41 #define __STDC_FORMAT_MACROS
42 #include <inttypes.h>
43 
44 #include <string.h>
45 #include <pthread.h>
46 #include <sys/prctl.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <errno.h>
50 #include "omx_vdec.h"
51 #include "vidc_common.h"
52 #include <fcntl.h>
53 #include <limits.h>
54 #include <stdlib.h>
55 #ifdef HYPERVISOR
56 #include "hypv_intercept.h"
57 #endif
58 #include <media/hardware/HardwareAPI.h>
59 #include <sys/eventfd.h>
60 #include "PlatformConfig.h"
61 #include <linux/dma-buf.h>
62 #include <linux/videodev2.h>
63 
64 #if !defined(_ANDROID_) || defined(SYS_IOCTL)
65 #include <sys/ioctl.h>
66 #include <sys/mman.h>
67 #endif
68 
69 #ifdef _ANDROID_
70 #include <cutils/properties.h>
71 
72 #ifdef _QUERY_DISP_RES_
73 #include "display_config.h"
74 #endif
75 #endif
76 
77 #ifdef _USE_GLIB_
78 #include <glib.h>
79 #define strlcpy g_strlcpy
80 #endif
81 
82 #include <qdMetaData.h>
83 #include <gralloc_priv.h>
84 
85 #ifdef ANDROID_JELLYBEAN_MR2
86 #include "QComOMXMetadata.h"
87 #endif
88 
89 #define BUFFER_LOG_LOC "/data/vendor/media"
90 
91 #ifdef OUTPUT_EXTRADATA_LOG
92 FILE *outputExtradataFile;
93 char output_extradata_filename [] = "/data/vendor/media/extradata";
94 #endif
95 
96 #define DEFAULT_FPS 30
97 #define MAX_SUPPORTED_FPS 240
98 #define DEFAULT_WIDTH_ALIGNMENT 128
99 #define DEFAULT_HEIGHT_ALIGNMENT 32
100 
101 #define POLL_TIMEOUT 0x7fffffff
102 
103 #ifdef _ANDROID_
104 extern "C" {
105 #include<utils/Log.h>
106 }
107 #endif//_ANDROID_
108 
109 #define SZ_4K 0x1000
110 #define SZ_1M 0x100000
111 
112 #define PREFETCH_PIXEL_BUFFER_COUNT 16
113 #define PREFETCH_NON_PIXEL_BUFFER_COUNT 1
114 
115 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
116 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
117 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
118 #undef ALIGN
119 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
120 
121 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA \
122                            | OMX_DISPLAY_INFO_EXTRADATA | OMX_UBWC_CR_STATS_INFO_EXTRADATA)
123 
124 // Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default
125 #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010
126 
127 #ifndef ION_FLAG_CP_BITSTREAM
128 #define ION_FLAG_CP_BITSTREAM 0
129 #endif
130 
131 #ifndef ION_FLAG_CP_PIXEL
132 #define ION_FLAG_CP_PIXEL 0
133 #endif
134 
135 #ifdef SLAVE_SIDE_CP
136 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
137 #define SECURE_ALIGN SZ_1M
138 #define SECURE_FLAGS_INPUT_BUFFER ION_FLAG_SECURE
139 #define SECURE_FLAGS_OUTPUT_BUFFER ION_FLAG_SECURE
140 #else //MASTER_SIDE_CP
141 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
142 #define SECURE_ALIGN SZ_4K
143 #define SECURE_FLAGS_INPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_BITSTREAM)
144 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_PIXEL)
145 #endif
146 
147 #define LUMINANCE_DIV_FACTOR 10000.0
148 #define LUMINANCE_MAXDISPLAY_CDM2 1000
149 
150 /* defined in mp-ctl.h */
151 #define MPCTLV3_VIDEO_DECODE_PB_HINT 0x41C04000
152 
153 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
154 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
155 
156 /*
157 To enable sending vp9/hevc hdr10plus metadata via private gralloc
158 handle to display, define HDR10PLUS_SETMETADATA_ENABLE as 1.This
159 disables sending metadata via framework. To enable sending vp9/hevc
160 hdr10plus metadata via framework, define HDR10PLUS_SETMETADATA_ENABLE
161 as 0. This disables sending metadata via gralloc handle.
162 */
163 #define HDR10_SETMETADATA_ENABLE 0
164 
165 using namespace android;
166 
167 #ifdef HYPERVISOR
168 #define ioctl(x, y, z) hypv_ioctl(x, y, z)
169 #define poll(x, y, z)  hypv_poll(x, y, z)
170 #endif
171 
172 static OMX_U32 maxSmoothStreamingWidth = 1920;
173 static OMX_U32 maxSmoothStreamingHeight = 1088;
174 
print_omx_buffer(const char * str,OMX_BUFFERHEADERTYPE * pHeader)175 void print_omx_buffer(const char *str, OMX_BUFFERHEADERTYPE *pHeader)
176 {
177     if (!pHeader)
178         return;
179 
180     DEBUG_PRINT_HIGH("%s: Header %p buffer %p alloclen %d offset %d filledlen %d timestamp %lld flags %#x",
181         str, pHeader, pHeader->pBuffer, pHeader->nAllocLen,
182         pHeader->nOffset, pHeader->nFilledLen,
183         pHeader->nTimeStamp, pHeader->nFlags);
184 }
185 
print_v4l2_buffer(const char * str,struct v4l2_buffer * v4l2)186 void print_v4l2_buffer(const char *str, struct v4l2_buffer *v4l2)
187 {
188     if (!v4l2)
189         return;
190 
191     if (v4l2->length == 1)
192         DEBUG_PRINT_HIGH(
193             "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x\n",
194             str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
195             "OUTPUT" : "CAPTURE", v4l2->index,
196             v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
197             v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
198             v4l2->m.planes[0].bytesused, v4l2->flags);
199     else
200         DEBUG_PRINT_HIGH(
201             "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x, extradata: fd %d off %d size %d filled %d\n",
202             str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
203             "OUTPUT" : "CAPTURE", v4l2->index,
204             v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
205             v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
206             v4l2->m.planes[0].bytesused, v4l2->m.planes[1].reserved[0],
207             v4l2->flags, v4l2->m.planes[1].reserved[1],
208             v4l2->m.planes[1].length, v4l2->m.planes[1].bytesused);
209 }
210 
async_message_thread(void * input)211 void* async_message_thread (void *input)
212 {
213     OMX_BUFFERHEADERTYPE *buffer;
214     struct v4l2_plane plane[VIDEO_MAX_PLANES];
215     struct pollfd pfds[2];
216     struct v4l2_buffer v4l2_buf;
217     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
218     struct v4l2_event dqevent;
219     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
220     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
221     pfds[1].events = POLLIN | POLLERR;
222     pfds[0].fd = omx->drv_ctx.video_driver_fd;
223     pfds[1].fd = omx->m_poll_efd;
224     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
225     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
226     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
227     while (!omx->async_thread_force_stop) {
228         rc = poll(pfds, 2, POLL_TIMEOUT);
229         if (!rc) {
230             DEBUG_PRINT_ERROR("Poll timedout");
231             break;
232         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
233             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
234             break;
235         }
236         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
237             DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
238             break;
239         }
240         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
241             struct vdec_msginfo vdec_msg;
242             memset(&vdec_msg, 0, sizeof(vdec_msg));
243             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
244             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
245             v4l2_buf.length = omx->drv_ctx.num_planes;
246             v4l2_buf.m.planes = plane;
247             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
248                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
249                 vdec_msg.status_code=VDEC_S_SUCCESS;
250                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
251                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
252                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
253                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
254                     (uint64_t)v4l2_buf.timestamp.tv_usec;
255 
256                 if (omx->async_message_process(input,&vdec_msg) < 0) {
257                     DEBUG_PRINT_HIGH("async_message_thread Exited");
258                     break;
259                 }
260             }
261         }
262         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
263             struct vdec_msginfo vdec_msg;
264             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
265             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
266             v4l2_buf.length = 1;
267             v4l2_buf.m.planes = plane;
268             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
269                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
270                 vdec_msg.status_code=VDEC_S_SUCCESS;
271                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
272                 if (omx->async_message_process(input,&vdec_msg) < 0) {
273                     DEBUG_PRINT_HIGH("async_message_thread Exited");
274                     break;
275                 }
276             }
277         }
278         if (pfds[0].revents & POLLPRI) {
279             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
280             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
281                 struct vdec_msginfo vdec_msg;
282                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
283 
284                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
285                 vdec_msg.status_code=VDEC_S_SUCCESS;
286                 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
287                 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
288                 vdec_msg.msgdata.output_frame.flags = true; // INSUFFICIENT event
289                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
290                 omx->dpb_bit_depth = ptr[2];
291                 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth - %d", ptr[3]);
292                 omx->m_progressive = ptr[3];
293                 DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct - %d", ptr[4]);
294                 omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
295                                       (omx_vdec:: EXCEPT_BT2020));
296                 DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace - %d", omx->m_color_space);
297                 if (omx->async_message_process(input,&vdec_msg) < 0) {
298                     DEBUG_PRINT_HIGH("async_message_thread Exited");
299                     break;
300                 }
301             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT) {
302 
303                 bool event_fields_changed = false;
304                 bool send_msg = false;
305                 omx_vdec::color_space_type tmp_color_space;
306                 struct vdec_msginfo vdec_msg;
307                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received sufficient");
308                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
309                 int tmp_profile = 0;
310                 int tmp_level = 0;
311                 int codec = omx->get_session_codec_type();
312                 event_fields_changed |= (omx->dpb_bit_depth != (int)ptr[2]);
313                 event_fields_changed |= (omx->m_progressive != (int)ptr[3]);
314                 tmp_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
315                                    (omx_vdec:: EXCEPT_BT2020));
316                 event_fields_changed |= (omx->m_color_space != tmp_color_space);
317 
318                 /*
319                  * If the resolution is different due to 16\32 pixel alignment,
320                  * let's handle as Sufficient. Ex : 1080 & 1088 or 2160 & 2176.
321                  * When FBD comes, component updates the clients with actual
322                  * resolution through set_buffer_geometry.
323                  */
324 
325                  event_fields_changed |= (omx->drv_ctx.video_resolution.frame_height != ptr[0]);
326                  event_fields_changed |= (omx->drv_ctx.video_resolution.frame_width != ptr[1]);
327 
328                  if ((codec == V4L2_PIX_FMT_H264) ||
329                      (codec  == V4L2_PIX_FMT_HEVC)) {
330                      if (profile_level_converter::convert_v4l2_profile_to_omx(
331                                                          codec, ptr[9], &tmp_profile) &&
332                          profile_level_converter::convert_v4l2_level_to_omx(
333                                                          codec, ptr[10], &tmp_level)) {
334                          event_fields_changed |= (omx->mClientSessionForSufficiency &&
335                                                   ((tmp_profile != (int)omx->mClientSetProfile) ||
336                                                    (tmp_level > (int)omx->mClientSetLevel)));
337                      }
338                  }
339 
340                  if (!omx->is_down_scalar_enabled && omx->m_is_split_mode &&
341                         (omx->drv_ctx.video_resolution.frame_height != ptr[0] ||
342                         omx->drv_ctx.video_resolution.frame_width != ptr[1])) {
343                      event_fields_changed = true;
344                  }
345 
346                  if (event_fields_changed) {
347                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old Resolution(H,W) = (%d,%d) New Resolution(H,W) = (%d,%d))",
348                                      omx->drv_ctx.video_resolution.frame_height,
349                                      omx->drv_ctx.video_resolution.frame_width,
350                                      ptr[0], ptr[1]);
351                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old bitdepth = %d New bitdepth = %d",
352                                      omx->dpb_bit_depth, ptr[2]);
353                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old picstruct = %d New picstruct = %d",
354                                      omx->m_progressive, ptr[3]);
355                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Old colorSpace = %s New colorspace = %s",
356                                      (omx->m_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"),
357                                      (tmp_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"));
358                     DEBUG_PRINT_HIGH("Client Session for sufficiency feature is %s", omx->mClientSessionForSufficiency ? "enabled": "disabled");
359                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Client (Profile,Level) = (%d,%d) bitstream(Profile,Level) = (%d,%d))",
360                                      omx->mClientSetProfile,
361                                      omx->mClientSetLevel,
362                                      tmp_profile, tmp_level);
363                     omx->dpb_bit_depth = ptr[2];
364                     omx->m_progressive = ptr[3];
365                     omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
366                                        (omx_vdec:: EXCEPT_BT2020));
367                     send_msg = true;
368                     vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
369                     vdec_msg.status_code=VDEC_S_SUCCESS;
370                     vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
371                     vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
372                     vdec_msg.msgdata.output_frame.flags = false; // SUFFICIENT event
373                 } else {
374                     struct v4l2_decoder_cmd dec;
375                     memset(&dec, 0, sizeof(dec));
376                     dec.cmd = V4L2_QCOM_CMD_SESSION_CONTINUE;
377                     rc = ioctl(pfds[0].fd, VIDIOC_DECODER_CMD, &dec);
378                     if (rc < 0) {
379                         DEBUG_PRINT_ERROR("Session continue failed");
380                         send_msg = true;
381                         vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
382                         vdec_msg.status_code=VDEC_S_SUCCESS;
383                     } else {
384                         DEBUG_PRINT_HIGH("Sent Session continue");
385                     }
386                 }
387 
388                 if (send_msg) {
389                     if (omx->async_message_process(input,&vdec_msg) < 0) {
390                         DEBUG_PRINT_HIGH("async_message_thread Exited");
391                         break;
392                     }
393                 }
394 
395             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
396                 struct vdec_msginfo vdec_msg;
397                 uint32_t flush_type = *(uint32_t *)dqevent.u.data;
398                 // Old driver doesn't send flushType information.
399                 // To make this backward compatible fallback to old approach
400                 // if the flush_type is not present.
401                 vdec_msg.status_code=VDEC_S_SUCCESS;
402                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) {
403                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
404                     DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
405                     if (omx->async_message_process(input,&vdec_msg) < 0) {
406                         DEBUG_PRINT_HIGH("async_message_thread Exited");
407                         break;
408                     }
409                 }
410 
411                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) {
412                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
413                     DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
414                     if (omx->async_message_process(input,&vdec_msg) < 0) {
415                         DEBUG_PRINT_HIGH("async_message_thread Exited");
416                         break;
417                     }
418                 }
419             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
420                 struct vdec_msginfo vdec_msg;
421                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
422                 vdec_msg.status_code=VDEC_S_SUCCESS;
423                 DEBUG_PRINT_ERROR("HW Overload received");
424                 if (omx->async_message_process(input,&vdec_msg) < 0) {
425                     DEBUG_PRINT_HIGH("async_message_thread Exited");
426                     break;
427                 }
428             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
429                 struct vdec_msginfo vdec_msg;
430                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
431                 vdec_msg.status_code=VDEC_S_SUCCESS;
432                 DEBUG_PRINT_ERROR("HW Unsupported received");
433                 if (omx->async_message_process(input,&vdec_msg) < 0) {
434                     DEBUG_PRINT_HIGH("async_message_thread Exited");
435                     break;
436                 }
437             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
438                 struct vdec_msginfo vdec_msg;
439                 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
440                 vdec_msg.status_code = VDEC_S_SUCCESS;
441                 DEBUG_PRINT_HIGH("SYS Error Recieved");
442                 if (omx->async_message_process(input,&vdec_msg) < 0) {
443                     DEBUG_PRINT_HIGH("async_message_thread Exited");
444                     break;
445                 }
446             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
447                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
448 
449                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
450             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
451                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
452                 struct vdec_msginfo vdec_msg;
453 
454                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
455 
456                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
457                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
458                 v4l2_buf.length = omx->drv_ctx.num_planes;
459                 v4l2_buf.m.planes = plane;
460                 v4l2_buf.index = ptr[5];
461                 v4l2_buf.flags = 0;
462 
463                 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
464                 vdec_msg.status_code = VDEC_S_SUCCESS;
465                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
466                 vdec_msg.msgdata.output_frame.len = 0;
467                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
468                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
469                     (uint64_t)ptr[4];
470                 if (omx->async_message_process(input,&vdec_msg) < 0) {
471                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
472                     break;
473                 }
474             } else {
475                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
476                 continue;
477             }
478         }
479     }
480     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
481     return NULL;
482 }
483 
message_thread_dec(void * input)484 void* message_thread_dec(void *input)
485 {
486     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
487     int res = 0;
488 
489     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
490     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
491     while (!omx->message_thread_stop) {
492         res = omx->signal.wait(2 * 1000000000);
493         if (res == ETIMEDOUT || omx->message_thread_stop) {
494             continue;
495         } else if (res) {
496             DEBUG_PRINT_ERROR("omx_vdec: message_thread_dec wait on condition failed, exiting");
497             break;
498         }
499         omx->process_event_cb(omx);
500     }
501     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
502     return 0;
503 }
504 
post_message(omx_vdec * omx,unsigned char id)505 void post_message(omx_vdec *omx, unsigned char id)
506 {
507     (void)id;
508     omx->signal.signal();
509 }
510 
511 // omx_cmd_queue destructor
~omx_cmd_queue()512 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
513 {
514     // Nothing to do
515 }
516 
517 // omx cmd queue constructor
omx_cmd_queue()518 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
519 {
520     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
521 }
522 
523 // omx cmd queue insert
insert_entry(unsigned long p1,unsigned long p2,unsigned long id)524 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
525 {
526     bool ret = true;
527     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
528         m_q[m_write].id       = id;
529         m_q[m_write].param1   = p1;
530         m_q[m_write].param2   = p2;
531         m_write++;
532         m_size ++;
533         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
534             m_write = 0;
535         }
536     } else {
537         ret = false;
538         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
539     }
540     return ret;
541 }
542 
543 // omx cmd queue pop
pop_entry(unsigned long * p1,unsigned long * p2,unsigned long * id)544 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
545 {
546     bool ret = true;
547     if (m_size > 0) {
548         *id = m_q[m_read].id;
549         *p1 = m_q[m_read].param1;
550         *p2 = m_q[m_read].param2;
551         // Move the read pointer ahead
552         ++m_read;
553         --m_size;
554         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
555             m_read = 0;
556         }
557     } else {
558         ret = false;
559     }
560     return ret;
561 }
562 
563 // Retrieve the first mesg type in the queue
get_q_msg_type()564 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
565 {
566     return m_q[m_read].id;
567 }
568 
569 #ifdef _ANDROID_
ts_arr_list()570 omx_vdec::ts_arr_list::ts_arr_list()
571 {
572     //initialize timestamps array
573     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
574 }
~ts_arr_list()575 omx_vdec::ts_arr_list::~ts_arr_list()
576 {
577     //free m_ts_arr_list?
578 }
579 
insert_ts(OMX_TICKS ts)580 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
581 {
582     bool ret = true;
583     bool duplicate_ts = false;
584     int idx = 0;
585 
586     //insert at the first available empty location
587     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
588         if (!m_ts_arr_list[idx].valid) {
589             //found invalid or empty entry, save timestamp
590             m_ts_arr_list[idx].valid = true;
591             m_ts_arr_list[idx].timestamp = ts;
592             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
593                     ts, idx);
594             break;
595         }
596     }
597 
598     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
599         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
600         ret = false;
601     }
602     return ret;
603 }
604 
pop_min_ts(OMX_TICKS & ts)605 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
606 {
607     bool ret = true;
608     int min_idx = -1;
609     OMX_TICKS min_ts = 0;
610     int idx = 0;
611 
612     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
613 
614         if (m_ts_arr_list[idx].valid) {
615             //found valid entry, save index
616             if (min_idx < 0) {
617                 //first valid entry
618                 min_ts = m_ts_arr_list[idx].timestamp;
619                 min_idx = idx;
620             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
621                 min_ts = m_ts_arr_list[idx].timestamp;
622                 min_idx = idx;
623             }
624         }
625 
626     }
627 
628     if (min_idx < 0) {
629         //no valid entries found
630         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
631         ts = 0;
632         ret = false;
633     } else {
634         ts = m_ts_arr_list[min_idx].timestamp;
635         m_ts_arr_list[min_idx].valid = false;
636         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
637                 ts, min_idx);
638     }
639 
640     return ret;
641 
642 }
643 
644 
reset_ts_list()645 bool omx_vdec::ts_arr_list::reset_ts_list()
646 {
647     bool ret = true;
648     int idx = 0;
649 
650     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
651     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
652         m_ts_arr_list[idx].valid = false;
653     }
654     return ret;
655 }
656 #endif
657 
658 // factory function executed by the core to create instances
get_omx_component_factory_fn(void)659 void *get_omx_component_factory_fn(void)
660 {
661     return (new omx_vdec);
662 }
663 
is_platform_tp10capture_supported()664 bool is_platform_tp10capture_supported()
665 {
666     DEBUG_PRINT_HIGH("TP10 on capture port is supported");
667     return true;
668 }
669 
get_session_codec_type()670 inline int omx_vdec::get_session_codec_type()
671 {
672     return output_capability;
673 }
674 /* ======================================================================
675    FUNCTION
676    omx_vdec::omx_vdec
677 
678    DESCRIPTION
679    Constructor
680 
681    PARAMETERS
682    None
683 
684    RETURN VALUE
685    None.
686    ========================================================================== */
omx_vdec()687 omx_vdec::omx_vdec(): m_error_propogated(false),
688     m_state(OMX_StateInvalid),
689     m_app_data(NULL),
690     m_inp_mem_ptr(NULL),
691     m_out_mem_ptr(NULL),
692     m_intermediate_out_mem_ptr(NULL),
693     m_client_output_extradata_mem_ptr(NULL),
694     input_flush_progress (false),
695     output_flush_progress (false),
696     input_use_buffer (false),
697     output_use_buffer (false),
698     ouput_egl_buffers(false),
699     m_use_output_pmem(OMX_FALSE),
700     pending_input_buffers(0),
701     pending_output_buffers(0),
702     m_out_bm_count(0),
703     m_inp_bm_count(0),
704     m_out_extradata_bm_count(0),
705     m_inp_bPopulated(OMX_FALSE),
706     m_out_bPopulated(OMX_FALSE),
707     m_flags(0),
708     m_inp_bEnabled(OMX_TRUE),
709     m_out_bEnabled(OMX_TRUE),
710     m_in_alloc_cnt(0),
711     m_platform_list(NULL),
712     m_platform_entry(NULL),
713     m_pmem_info(NULL),
714     h264_parser(NULL),
715     arbitrary_bytes (false),
716     psource_frame (NULL),
717     pdest_frame (NULL),
718     m_inp_heap_ptr (NULL),
719     m_phdr_pmem_ptr(NULL),
720     m_heap_inp_bm_count (0),
721     codec_type_parse ((codec_type)0),
722     first_frame_meta (true),
723     frame_count (0),
724     nal_count (0),
725     nal_length(0),
726     look_ahead_nal (false),
727     first_frame(0),
728     first_buffer(NULL),
729     first_frame_size (0),
730     m_device_file_ptr(NULL),
731     h264_last_au_ts(LLONG_MAX),
732     h264_last_au_flags(0),
733     m_disp_hor_size(0),
734     m_disp_vert_size(0),
735     prev_ts(LLONG_MAX),
736     prev_ts_actual(LLONG_MAX),
737     rst_prev_ts(true),
738     frm_int(0),
739     m_fps_received(0),
740     m_fps_prev(0),
741     m_drc_enable(0),
742     in_reconfig(false),
743     c2d_enable_pending(false),
744     m_display_id(NULL),
745     client_extradata(0),
746 #ifdef _ANDROID_
747     m_enable_android_native_buffers(OMX_FALSE),
748     m_use_android_native_buffers(OMX_FALSE),
749 #endif
750     m_disable_dynamic_buf_mode(0),
751     m_desc_buffer_ptr(NULL),
752     secure_mode(false),
753     allocate_native_handle(false),
754     client_set_fps(false),
755     stereo_output_mode(HAL_NO_3D),
756     m_last_rendered_TS(-1),
757     m_dec_hfr_fps(0),
758     m_dec_secure_prefetch_size_internal(0),
759     m_dec_secure_prefetch_size_output(0),
760     m_arb_mode_override(0),
761     m_queued_codec_config_count(0),
762     secure_scaling_to_non_secure_opb(false),
763     m_force_compressed_for_dpb(true),
764     m_is_display_session(false),
765     m_prefetch_done(0),
766     m_is_split_mode(false),
767     m_buffer_error(false)
768 {
769     m_poll_efd = -1;
770     memset(&drv_ctx, 0, sizeof(drv_ctx));
771     drv_ctx.video_driver_fd = -1;
772     drv_ctx.extradata_info.ion.data_fd = -1;
773     drv_ctx.extradata_info.ion.dev_fd = -1;
774     /* Assumption is that , to begin with , we have all the frames with decoder */
775     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
776     memset(&m_debug,0,sizeof(m_debug));
777 #ifdef _ANDROID_
778 
779     char property_value[PROPERTY_VALUE_MAX] = {0};
780     property_get("vendor.vidc.debug.level", property_value, "1");
781     debug_level = strtoul(property_value, NULL, 16);
782     property_value[0] = '\0';
783 
784     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
785 
786     // TODO: Support in XML
787     perf_flag = 0;
788     if (perf_flag) {
789         DEBUG_PRINT_HIGH("perf flag is %d", perf_flag);
790         dec_time.start();
791     }
792     proc_frms = latency = 0;
793     prev_n_filled_len = 0;
794 
795     Platform::Config::getInt32(Platform::vidc_dec_log_in,
796             (int32_t *)&m_debug.in_buffer_log, 0);
797     Platform::Config::getInt32(Platform::vidc_dec_log_out,
798             (int32_t *)&m_debug.out_buffer_log, 0);
799 
800     Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_internal,
801             (int32_t *)&m_dec_secure_prefetch_size_internal, 0);
802     Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_output,
803             (int32_t *)&m_dec_secure_prefetch_size_output, 0);
804 
805     DEBUG_PRINT_HIGH("Prefetch size internal = %d, output = %d",
806             m_dec_secure_prefetch_size_internal, m_dec_secure_prefetch_size_output);
807 
808     Platform::Config::getInt32(Platform::vidc_dec_arb_mode_override,
809             (int32_t *)&m_arb_mode_override, 0);
810 
811     Platform::Config::getInt32(Platform::vidc_perf_control_enable,
812             (int32_t *)&m_perf_control.m_perf_control_enable, 0);
813     if (m_perf_control.m_perf_control_enable) {
814         DEBUG_PRINT_HIGH("perf cotrol enabled");
815         m_perf_control.load_perf_library();
816     }
817 
818     property_value[0] = '\0';
819     property_get("vendor.vidc.dec.log.in", property_value, "0");
820     m_debug.in_buffer_log |= atoi(property_value);
821 
822     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.in value is %d", m_debug.in_buffer_log);
823 
824     property_value[0] = '\0';
825     property_get("vendor.vidc.dec.log.out", property_value, "0");
826     m_debug.out_buffer_log |= atoi(property_value);
827 
828     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.out value is %d", m_debug.out_buffer_log);
829 
830     property_value[0] = '\0';
831     property_get("vendor.vidc.dec.log.cc.out", property_value, "0");
832     m_debug.out_cc_buffer_log |= atoi(property_value);
833 
834     DEBUG_PRINT_HIGH("vendor.vidc.dec.log.cc.out value is %d", m_debug.out_buffer_log);
835 
836     property_value[0] = '\0';
837     property_get("vendor.vidc.dec.meta.log.out", property_value, "0");
838     m_debug.out_meta_buffer_log = atoi(property_value);
839 
840     property_value[0] = '\0';
841     property_get("vendor.vidc.log.loc", property_value, BUFFER_LOG_LOC);
842     if (*property_value)
843         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
844 
845     struct timeval te;
846     gettimeofday(&te, NULL);
847     m_debug.session_id = te.tv_sec*1000LL + te.tv_usec/1000;
848     m_debug.seq_count = 0;
849 
850 #ifdef _UBWC_
851     property_value[0] = '\0';
852     property_get("vendor.gralloc.disable_ubwc", property_value, "0");
853     m_disable_ubwc_mode = atoi(property_value);
854     DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
855 #else
856     m_disable_ubwc_mode = true;
857 #endif
858 #endif
859     memset(&m_cmp,0,sizeof(m_cmp));
860     memset(&m_cb,0,sizeof(m_cb));
861     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
862     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
863     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
864     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
865     memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
866     memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
867     memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
868     memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
869     m_demux_entries = 0;
870     msg_thread_id = 0;
871     async_thread_id = 0;
872     msg_thread_created = false;
873     async_thread_created = false;
874     async_thread_force_stop = false;
875     message_thread_stop = false;
876 #ifdef _ANDROID_ICS_
877     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
878 #endif
879 
880     /* invalidate m_frame_pack_arrangement */
881     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
882     m_frame_pack_arrangement.cancel_flag = 1;
883 
884     drv_ctx.timestamp_adjust = false;
885     m_vendor_config.pData = NULL;
886     pthread_mutex_init(&m_lock, NULL);
887     pthread_mutex_init(&c_lock, NULL);
888     pthread_mutex_init(&buf_lock, NULL);
889     pthread_mutex_init(&m_hdr10pluslock, NULL);
890     sem_init(&m_cmd_lock,0,0);
891     sem_init(&m_safe_flush, 0, 0);
892     streaming[CAPTURE_PORT] =
893         streaming[OUTPUT_PORT] = false;
894 #ifdef _ANDROID_
895     // TODO: Support in XML
896     m_debug_extradata = 0;
897 #endif
898     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
899     client_buffers.set_vdec_client(this);
900     dynamic_buf_mode = false;
901     is_down_scalar_enabled = false;
902     m_downscalar_width = 0;
903     m_downscalar_height = 0;
904     m_force_down_scalar = 0;
905     m_reconfig_height = 0;
906     m_reconfig_width = 0;
907     m_smoothstreaming_mode = false;
908     m_smoothstreaming_width = 0;
909     m_smoothstreaming_height = 0;
910     m_decode_order_mode = false;
911     m_perf_control.perf_lock_acquire();
912     m_client_req_turbo_mode = false;
913     is_q6_platform = false;
914     m_input_pass_buffer_fd = false;
915     memset(&m_extradata_info, 0, sizeof(m_extradata_info));
916     m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
917     m_client_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
918     m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
919     m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
920     m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
921 
922     m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
923     m_internal_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
924     m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
925     m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
926     m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
927     m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
928 
929     m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
930     m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
931 
932     m_dither_config = DITHER_DISABLE;
933 
934     DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config);
935     m_etb_count = 0;
936     m_etb_timestamp = 0;
937 
938     m_color_space = EXCEPT_BT2020;
939 
940     init_color_aspects_map();
941 
942     profile_level_converter::init();
943     mClientSessionForSufficiency = false;
944     mClientSetProfile = 0;
945     mClientSetLevel = 0;
946 #ifdef USE_GBM
947      drv_ctx.gbm_device_fd = -1;
948 #endif
949 }
950 
951 static const int event_type[] = {
952     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
953     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
954     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
955     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
956     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
957     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
958     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
959     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
960 };
961 
subscribe_to_events(int fd)962 static OMX_ERRORTYPE subscribe_to_events(int fd)
963 {
964     OMX_ERRORTYPE eRet = OMX_ErrorNone;
965     struct v4l2_event_subscription sub;
966     int array_sz = sizeof(event_type)/sizeof(int);
967     int i,rc;
968     if (fd < 0) {
969         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
970         return OMX_ErrorBadParameter;
971     }
972 
973     for (i = 0; i < array_sz; ++i) {
974         memset(&sub, 0, sizeof(sub));
975         sub.type = event_type[i];
976         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
977         if (rc) {
978             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
979             break;
980         }
981     }
982     if (i < array_sz) {
983         for (--i; i >=0 ; i--) {
984             memset(&sub, 0, sizeof(sub));
985             sub.type = event_type[i];
986             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
987             if (rc)
988                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
989         }
990         eRet = OMX_ErrorNotImplemented;
991     }
992     return eRet;
993 }
994 
995 
unsubscribe_to_events(int fd)996 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
997 {
998     OMX_ERRORTYPE eRet = OMX_ErrorNone;
999     struct v4l2_event_subscription sub;
1000     int array_sz = sizeof(event_type)/sizeof(int);
1001     int i,rc;
1002     if (fd < 0) {
1003         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
1004         return OMX_ErrorBadParameter;
1005     }
1006 
1007     for (i = 0; i < array_sz; ++i) {
1008         memset(&sub, 0, sizeof(sub));
1009         sub.type = event_type[i];
1010         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1011         if (rc) {
1012             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1013             break;
1014         }
1015     }
1016     return eRet;
1017 }
1018 
1019 /* ======================================================================
1020    FUNCTION
1021    omx_vdec::~omx_vdec
1022 
1023    DESCRIPTION
1024    Destructor
1025 
1026    PARAMETERS
1027    None
1028 
1029    RETURN VALUE
1030    None.
1031    ========================================================================== */
~omx_vdec()1032 omx_vdec::~omx_vdec()
1033 {
1034     m_pmem_info = NULL;
1035     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
1036     if (msg_thread_created) {
1037         DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
1038         message_thread_stop = true;
1039         post_message(this, OMX_COMPONENT_CLOSE_MSG);
1040         DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
1041         pthread_join(msg_thread_id,NULL);
1042     }
1043     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
1044     if(eventfd_write(m_poll_efd, 1)) {
1045          DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1046          async_thread_force_stop = true;
1047     }
1048     if (async_thread_created)
1049         pthread_join(async_thread_id,NULL);
1050 
1051     if (m_prefetch_done & 0x1)
1052         prefetch_buffers(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, ION_IOC_DRAIN, ION_FLAG_CP_PIXEL);
1053     if (m_prefetch_done & 0x2)
1054         prefetch_buffers(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, ION_IOC_DRAIN, ION_FLAG_CP_NON_PIXEL);
1055 
1056     unsubscribe_to_events(drv_ctx.video_driver_fd);
1057     close(m_poll_efd);
1058 #ifdef HYPERVISOR
1059     hypv_close(drv_ctx.video_driver_fd);
1060 #else
1061     close(drv_ctx.video_driver_fd);
1062 #endif
1063     clear_hdr10plusinfo();
1064     pthread_mutex_destroy(&m_lock);
1065     pthread_mutex_destroy(&c_lock);
1066     pthread_mutex_destroy(&buf_lock);
1067     pthread_mutex_destroy(&m_hdr10pluslock);
1068     sem_destroy(&m_cmd_lock);
1069     if (perf_flag) {
1070         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
1071         dec_time.end();
1072     }
1073     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
1074     m_perf_control.perf_lock_release();
1075 }
1076 
set_dpb(bool is_split_mode)1077 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode)
1078 {
1079     int rc = 0;
1080     struct v4l2_ext_control ctrl[1];
1081     struct v4l2_ext_controls controls;
1082 
1083     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
1084     if (is_split_mode) {
1085         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
1086     } else {
1087         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
1088     }
1089 
1090     controls.count = 1;
1091     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
1092     controls.controls = ctrl;
1093 
1094     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
1095     if (rc) {
1096         DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
1097         return OMX_ErrorUnsupportedSetting;
1098     }
1099     m_is_split_mode = is_split_mode;
1100     return OMX_ErrorNone;
1101 
1102 }
1103 
decide_dpb_buffer_mode()1104 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
1105 {
1106     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1107     struct v4l2_format fmt;
1108     int rc = 0;
1109 
1110     // Default is Combined Mode
1111     bool enable_split = false;
1112     bool is_client_dest_format_non_ubwc = (
1113                      capture_capability != V4L2_PIX_FMT_NV12_UBWC &&
1114                      capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC);
1115     bool dither_enable = false;
1116     bool capability_changed = false;
1117 
1118     switch (m_dither_config) {
1119     case DITHER_DISABLE:
1120         dither_enable = false;
1121         break;
1122     case DITHER_COLORSPACE_EXCEPTBT2020:
1123         dither_enable = (m_color_space == EXCEPT_BT2020);
1124         break;
1125     case DITHER_ALL_COLORSPACE:
1126         dither_enable = true;
1127         break;
1128     default:
1129         DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config);
1130     }
1131 
1132     // Reset v4l2_foramt struct object
1133     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1134 
1135     if (is_client_dest_format_non_ubwc){
1136         // Assuming all the else blocks are for 8 bit depth
1137         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1138             enable_split = true;
1139             if(is_flexible_format){ // if flexible formats are expected, P010 is set for 10bit cases here
1140                  drv_ctx.output_format = VDEC_YUV_FORMAT_P010_VENUS;
1141                  capture_capability = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
1142                  capability_changed = true;
1143             }
1144         } else  if (m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE &&
1145                     eCompressionFormat != OMX_VIDEO_CodingMPEG2) {
1146             enable_split = true;
1147         } else {
1148             // Hardware does not support NV12+interlace clips.
1149             // Request NV12_UBWC and convert it to NV12+interlace using C2D
1150             // in combined mode
1151             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
1152             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
1153             capability_changed = true;
1154         }
1155     } else {
1156         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1157             enable_split = dither_enable;
1158 
1159             if (dither_enable) {
1160                 capture_capability = m_disable_ubwc_mode ?
1161                             V4L2_PIX_FMT_NV12 : V4L2_PIX_FMT_NV12_UBWC;
1162                 capability_changed = true;
1163             } else {
1164                 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
1165                 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
1166                 capability_changed = true;
1167             }
1168         }
1169         // 8 bit depth uses the default.
1170         // Combined mode
1171         // V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE
1172     }
1173 
1174     if (capability_changed == true) {
1175         // Get format for CAPTURE port
1176         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1177         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1178         if (rc) {
1179             DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__);
1180             return OMX_ErrorUnsupportedSetting;
1181         }
1182 
1183         // Set Capability for CAPTURE port if there is a change
1184         fmt.fmt.pix_mp.pixelformat = capture_capability;
1185         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1186         if (rc) {
1187             DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1188             return OMX_ErrorUnsupportedSetting;
1189         }
1190     }
1191     // Check the component for its valid current state
1192     if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
1193         !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
1194         DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
1195         return OMX_ErrorNone;
1196     }
1197     eRet = set_dpb(enable_split);
1198     if (eRet) {
1199         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
1200     }
1201 
1202     return eRet;
1203 }
1204 
check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)1205 bool omx_vdec::check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)
1206 {
1207     if(required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
1208          required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus) {
1209          //for now, the flexible formats should be NV12 by default for 8bit cases
1210          //it will change to P010 after 10bit port-reconfig accordingly
1211        return TRUE;
1212     }
1213     else {
1214        return FALSE;
1215     }
1216 }
1217 
enable_downscalar()1218 int omx_vdec::enable_downscalar()
1219 {
1220     int rc = 0;
1221     struct v4l2_control control;
1222     struct v4l2_format fmt;
1223 
1224     if (is_down_scalar_enabled) {
1225         DEBUG_PRINT_LOW("%s: already enabled", __func__);
1226         return 0;
1227     }
1228 
1229     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
1230     rc = decide_dpb_buffer_mode();
1231     if (rc) {
1232         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
1233         return rc;
1234     }
1235     is_down_scalar_enabled = true;
1236 
1237     return 0;
1238 }
1239 
disable_downscalar()1240 int omx_vdec::disable_downscalar()
1241 {
1242     int rc = 0;
1243     struct v4l2_control control;
1244 
1245     if (!is_down_scalar_enabled) {
1246         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
1247         return 0;
1248     }
1249     rc = decide_dpb_buffer_mode();
1250     if (rc < 0) {
1251         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
1252         return rc;
1253     }
1254     is_down_scalar_enabled = false;
1255 
1256     return rc;
1257 }
1258 
decide_downscalar()1259 int omx_vdec::decide_downscalar()
1260 {
1261     int rc = 0;
1262     struct v4l2_format fmt;
1263     enum color_fmts color_format;
1264     OMX_U32 width, height;
1265     OMX_BOOL isPortraitVideo = OMX_FALSE;
1266 
1267     if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
1268         rc = disable_downscalar();
1269         if (rc) {
1270             DEBUG_PRINT_ERROR("Disable downscalar failed!");
1271             return rc;
1272         }
1273         return 0;
1274     }
1275 
1276 #ifdef _QUERY_DISP_RES_
1277     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1278     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1279     fmt.fmt.pix_mp.pixelformat = capture_capability;
1280     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1281     if (rc < 0) {
1282        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1283        return rc;
1284     }
1285     isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
1286     if (!m_downscalar_width || !m_downscalar_height) {
1287         qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
1288         int prim_config, ext_config, virt_config;
1289 
1290         prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
1291         dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
1292         DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d  dpa.yres=%d   dpa.xdpi = %f  dpa.ydpi = %f ",
1293             __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
1294 
1295         ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
1296         dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
1297         DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d  dsa.yres = %d   dsa.xdpi = %f  dsa.ydpi = %f ",
1298             __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
1299 
1300         virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
1301         dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
1302         DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d  dva.yres = %d   dva.xdpi = %f  dva.ydpi = %f ",
1303             __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
1304 
1305         /* Below logic takes care of following conditions:
1306          *   1. Choose display resolution as maximum resolution of all the connected
1307          *      displays (secondary, primary, virtual), so that we do not downscale
1308          *      unnecessarily which might be supported on one of the display losing quality.
1309          *   2. Displays connected might be in landscape or portrait mode, so the xres might
1310          *      be smaller or greater than the yres. So we first take the max of the two
1311          *      in width and min of two in height and then rotate it if below point is true.
1312          *   3. Video might also be in portrait mode, so invert the downscalar width and
1313          *      height for such cases.
1314          */
1315         if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
1316             m_downscalar_width = MAX(dsa.xres, dsa.yres);
1317             m_downscalar_height = MIN(dsa.xres, dsa.yres);
1318         } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
1319             m_downscalar_width = MAX(dva.xres, dva.yres);
1320             m_downscalar_height = MIN(dva.xres, dva.yres);
1321 
1322         } else {
1323             m_downscalar_width = MAX(dpa.xres, dpa.yres);
1324             m_downscalar_height = MIN(dpa.xres, dpa.yres);
1325         }
1326         if (isPortraitVideo) {
1327             // Swap width and height
1328             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1329             m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
1330             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1331         }
1332     }
1333     m_downscalar_width = ALIGN(m_downscalar_width, 128);
1334     m_downscalar_height = ALIGN(m_downscalar_height, 32);
1335 #endif
1336 
1337     if (!m_downscalar_width || !m_downscalar_height) {
1338         DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
1339         return 0;
1340     }
1341 
1342     if (m_force_down_scalar) {
1343         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
1344         return 0;
1345     }
1346 
1347     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1348     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1349     fmt.fmt.pix_mp.pixelformat = capture_capability;
1350     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1351     if (rc < 0) {
1352        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1353        return rc;
1354     }
1355 
1356     height = fmt.fmt.pix_mp.height;
1357     width = fmt.fmt.pix_mp.width;
1358 
1359     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
1360         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
1361 
1362     if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) &&
1363          m_is_display_session) {
1364         rc = enable_downscalar();
1365         if (rc < 0) {
1366             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
1367             return rc;
1368         }
1369 
1370         width = m_downscalar_width > fmt.fmt.pix_mp.width ?
1371                             fmt.fmt.pix_mp.width : m_downscalar_width;
1372         height = m_downscalar_height > fmt.fmt.pix_mp.height ?
1373                             fmt.fmt.pix_mp.height : m_downscalar_height;
1374         switch (capture_capability) {
1375             case V4L2_PIX_FMT_NV12:
1376                 color_format = COLOR_FMT_NV12;
1377                 break;
1378             case V4L2_PIX_FMT_NV12_UBWC:
1379                 color_format = COLOR_FMT_NV12_UBWC;
1380                 break;
1381             case V4L2_PIX_FMT_NV12_TP10_UBWC:
1382                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
1383                 break;
1384             default:
1385                 DEBUG_PRINT_ERROR("Color format not recognized\n");
1386                 rc = OMX_ErrorUndefined;
1387                 return rc;
1388         }
1389     } else {
1390 
1391         rc = disable_downscalar();
1392         if (rc < 0) {
1393             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
1394             return rc;
1395         }
1396     }
1397 
1398     memset(&fmt, 0x0, sizeof(struct v4l2_format));
1399     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1400     fmt.fmt.pix_mp.height = height;
1401     fmt.fmt.pix_mp.width = width;
1402     fmt.fmt.pix_mp.pixelformat = capture_capability;
1403     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1404     if (rc) {
1405         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1406         return rc;
1407     }
1408 
1409     rc = get_buffer_req(&drv_ctx.op_buf);
1410     if (rc) {
1411         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
1412         return rc;
1413     }
1414 
1415     return rc;
1416 }
1417 
1418 /* ======================================================================
1419    FUNCTION
1420    omx_vdec::OMXCntrlProcessMsgCb
1421 
1422    DESCRIPTION
1423    IL Client callbacks are generated through this routine. The decoder
1424    provides the thread context for this routine.
1425 
1426    PARAMETERS
1427    ctxt -- Context information related to the self.
1428    id   -- Event identifier. This could be any of the following:
1429    1. Command completion event
1430    2. Buffer done callback event
1431    3. Frame done callback event
1432 
1433    RETURN VALUE
1434    None.
1435 
1436    ========================================================================== */
process_event_cb(void * ctxt)1437 void omx_vdec::process_event_cb(void *ctxt)
1438 {
1439     unsigned long p1; // Parameter - 1
1440     unsigned long p2; // Parameter - 2
1441     unsigned long ident;
1442     unsigned qsize=0; // qsize
1443     omx_vdec *pThis = (omx_vdec *) ctxt;
1444 
1445     if (!pThis) {
1446         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
1447                 __func__);
1448         return;
1449     }
1450 
1451     // Protect the shared queue data structure
1452     do {
1453         /*Read the message id's from the queue*/
1454         pthread_mutex_lock(&pThis->m_lock);
1455         qsize = pThis->m_cmd_q.m_size;
1456         if (qsize) {
1457             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
1458         }
1459 
1460         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1461             qsize = pThis->m_ftb_q.m_size;
1462             if (qsize) {
1463                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
1464             }
1465         }
1466 
1467         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1468             qsize = pThis->m_etb_q.m_size;
1469             if (qsize) {
1470                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
1471             }
1472         }
1473         pthread_mutex_unlock(&pThis->m_lock);
1474 
1475         /*process message if we have one*/
1476         if (qsize > 0) {
1477             switch (ident) {
1478                 case OMX_COMPONENT_GENERATE_EVENT:
1479                     if (pThis->m_cb.EventHandler) {
1480                         switch (p1) {
1481                             case OMX_CommandStateSet:
1482                                 pThis->m_state = (OMX_STATETYPE) p2;
1483                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
1484                                         pThis->m_state);
1485                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1486                                         OMX_EventCmdComplete, p1, p2, NULL);
1487                                 break;
1488 
1489                             case OMX_EventError:
1490                                 if (p2 == OMX_StateInvalid) {
1491                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
1492                                     pThis->m_state = (OMX_STATETYPE) p2;
1493                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1494                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
1495                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
1496                                     pThis->omx_report_error();
1497                                 } else {
1498                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1499                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
1500                                 }
1501                                 break;
1502 
1503                             case OMX_CommandPortDisable:
1504                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
1505                                 if (BITMASK_PRESENT(&pThis->m_flags,
1506                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1507                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1508                                     break;
1509                                 }
1510                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
1511                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
1512                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
1513                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
1514                                     pThis->in_reconfig = false;
1515                                     pThis->client_buffers.enable_color_conversion(pThis->c2d_enable_pending);
1516                                     if (eRet !=  OMX_ErrorNone) {
1517                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
1518                                         pThis->omx_report_error();
1519                                         break;
1520                                     }
1521                                 }
1522                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1523                                         OMX_EventCmdComplete, p1, p2, NULL );
1524                                 break;
1525                             case OMX_CommandPortEnable:
1526                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
1527                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
1528                                         OMX_EventCmdComplete, p1, p2, NULL );
1529                                 break;
1530 
1531                             default:
1532                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1533                                         OMX_EventCmdComplete, p1, p2, NULL );
1534                                 break;
1535 
1536                         }
1537                     } else {
1538                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1539                     }
1540                     break;
1541                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
1542                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
1543                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1544                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
1545                         pThis->omx_report_error ();
1546                     }
1547                     break;
1548                 case OMX_COMPONENT_GENERATE_ETB: {
1549                         OMX_ERRORTYPE iret;
1550                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
1551                         if (iret == OMX_ErrorInsufficientResources) {
1552                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
1553                             pThis->omx_report_hw_overload ();
1554                         } else if (iret != OMX_ErrorNone) {
1555                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
1556                             pThis->omx_report_error ();
1557                         }
1558                     }
1559                     break;
1560 
1561                 case OMX_COMPONENT_GENERATE_FTB:
1562                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
1563                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1564                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
1565                         pThis->omx_report_error ();
1566                     }
1567                     break;
1568 
1569                 case OMX_COMPONENT_GENERATE_COMMAND:
1570                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
1571                             (OMX_U32)p2,(OMX_PTR)NULL);
1572                     break;
1573 
1574                 case OMX_COMPONENT_GENERATE_EBD:
1575 
1576                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
1577                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
1578                         pThis->omx_report_error ();
1579                     } else {
1580                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
1581                             pThis->time_stamp_dts.remove_time_stamp(
1582                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
1583                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1584                                     ?true:false);
1585                         }
1586 
1587                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
1588                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
1589                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
1590                             pThis->omx_report_error ();
1591                         }
1592                     }
1593                     break;
1594                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
1595                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
1596                                             if (p1) {
1597                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
1598                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1599                                                         ?true:false);
1600                                                 free(timestamp);
1601                                             }
1602                                         }
1603                                         break;
1604                 case OMX_COMPONENT_GENERATE_FBD:
1605                                         if (p2 != VDEC_S_SUCCESS) {
1606                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
1607                                             pThis->omx_report_error ();
1608                                             break;
1609                                         }
1610                                         if (pThis->fill_buffer_done(&pThis->m_cmp,
1611                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
1612                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
1613                                             pThis->omx_report_error ();
1614                                             break;
1615                                         }
1616 //#if !HDR10_SETMETADATA_ENABLE
1617                                         if (pThis->output_capability != V4L2_PIX_FMT_VP9 &&
1618                                             pThis->output_capability != V4L2_PIX_FMT_HEVC)
1619                                             break;
1620 
1621                                         if (!pThis->m_cb.EventHandler) {
1622                                             DEBUG_PRINT_ERROR("fill_buffer_done: null event handler");
1623                                             break;
1624                                         }
1625                                         bool is_list_empty;
1626                                         is_list_empty = false;
1627                                         pthread_mutex_lock(&pThis->m_hdr10pluslock);
1628                                         is_list_empty = pThis->m_hdr10pluslist.empty();
1629                                         pthread_mutex_unlock(&pThis->m_hdr10pluslock);
1630                                         if (!is_list_empty) {
1631                                             DEBUG_PRINT_LOW("fill_buffer_done: event config update");
1632                                             pThis->m_cb.EventHandler(&pThis->m_cmp,
1633                                                     pThis->m_app_data,
1634                                                     OMX_EventConfigUpdate,
1635                                                     OMX_CORE_OUTPUT_PORT_INDEX,
1636                                                     OMX_QTIIndexConfigDescribeHDR10PlusInfo, NULL);
1637                                         }
1638 //#endif
1639                                         break;
1640 
1641                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
1642                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete, flags %#llx",
1643                                                 (unsigned long long)pThis->m_flags);
1644                                         if (!pThis->input_flush_progress) {
1645                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1646                                         } else {
1647                                             pThis->execute_input_flush();
1648                                             if (pThis->m_cb.EventHandler) {
1649                                                 if (p2 != VDEC_S_SUCCESS) {
1650                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
1651                                                     pThis->omx_report_error ();
1652                                                 } else {
1653                                                     /*Check if we need generate event for Flush done*/
1654                                                     pThis->notify_flush_done(ctxt);
1655 
1656                                                     if (BITMASK_PRESENT(&pThis->m_flags,
1657                                                                 OMX_COMPONENT_IDLE_PENDING)) {
1658                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
1659                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
1660                                                             pThis->omx_report_error ();
1661                                                         } else {
1662                                                             pThis->streaming[OUTPUT_PORT] = false;
1663                                                         }
1664                                                         if (!pThis->output_flush_progress) {
1665                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
1666                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1667                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
1668                                                         }
1669                                                     }
1670                                                 }
1671                                             } else {
1672                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1673                                             }
1674                                         }
1675                                         break;
1676 
1677                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1678                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete, flags %#llx",
1679                                                 (unsigned long long)pThis->m_flags);
1680                                         if (!pThis->output_flush_progress) {
1681                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1682                                         } else {
1683                                             pThis->execute_output_flush();
1684                                             if (pThis->m_cb.EventHandler) {
1685                                                 if (p2 != VDEC_S_SUCCESS) {
1686                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1687                                                     pThis->omx_report_error ();
1688                                                 } else {
1689                                                     /*Check if we need generate event for Flush done*/
1690                                                     pThis->notify_flush_done(ctxt);
1691 
1692                                                     if (BITMASK_PRESENT(&pThis->m_flags,
1693                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1694                                                         DEBUG_PRINT_LOW("Internal flush complete");
1695                                                         BITMASK_CLEAR (&pThis->m_flags,
1696                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1697                                                         if (BITMASK_PRESENT(&pThis->m_flags,
1698                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1699                                                             pThis->post_event(OMX_CommandPortDisable,
1700                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
1701                                                                     OMX_COMPONENT_GENERATE_EVENT);
1702                                                             BITMASK_CLEAR (&pThis->m_flags,
1703                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1704                                                             BITMASK_CLEAR (&pThis->m_flags,
1705                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1706 
1707                                                         }
1708                                                     }
1709 
1710                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1711                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1712                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
1713                                                             pThis->omx_report_error ();
1714                                                             break;
1715                                                         }
1716                                                         pThis->streaming[CAPTURE_PORT] = false;
1717                                                         if (!pThis->input_flush_progress) {
1718                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
1719                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1720                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
1721                                                         }
1722                                                     }
1723                                                 }
1724                                             } else {
1725                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1726                                             }
1727                                         }
1728                                         break;
1729 
1730                 case OMX_COMPONENT_GENERATE_START_DONE:
1731                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE, flags %#llx",
1732                                                 (unsigned long long)pThis->m_flags);
1733                                         if (pThis->m_cb.EventHandler) {
1734                                             if (p2 != VDEC_S_SUCCESS) {
1735                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
1736                                                 pThis->omx_report_error ();
1737                                             } else {
1738                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
1739                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1740                                                     DEBUG_PRINT_LOW("Move to executing");
1741                                                     // Send the callback now
1742                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1743                                                     pThis->m_state = OMX_StateExecuting;
1744                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1745                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1746                                                             OMX_StateExecuting, NULL);
1747                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
1748                                                             OMX_COMPONENT_PAUSE_PENDING)) {
1749                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1750                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1751                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
1752                                                         pThis->omx_report_error ();
1753                                                     }
1754                                                 }
1755                                             }
1756                                         } else {
1757                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
1758                                         }
1759                                         break;
1760 
1761                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1762                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1763                                         if (pThis->m_cb.EventHandler) {
1764                                             if (p2 != VDEC_S_SUCCESS) {
1765                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1766                                                 pThis->omx_report_error ();
1767                                             } else {
1768                                                 pThis->complete_pending_buffer_done_cbs();
1769                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1770                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1771                                                     //Send the callback now
1772                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1773                                                     pThis->m_state = OMX_StatePause;
1774                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1775                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1776                                                             OMX_StatePause, NULL);
1777                                                 }
1778                                             }
1779                                         } else {
1780                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1781                                         }
1782 
1783                                         break;
1784 
1785                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1786                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1787                                         if (pThis->m_cb.EventHandler) {
1788                                             if (p2 != VDEC_S_SUCCESS) {
1789                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1790                                                 pThis->omx_report_error ();
1791                                             } else {
1792                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1793                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
1794                                                     // Send the callback now
1795                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1796                                                     pThis->m_state = OMX_StateExecuting;
1797                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1798                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1799                                                             OMX_StateExecuting,NULL);
1800                                                 }
1801                                             }
1802                                         } else {
1803                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1804                                         }
1805 
1806                                         break;
1807 
1808                 case OMX_COMPONENT_GENERATE_STOP_DONE:
1809                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1810                                         if (pThis->m_cb.EventHandler) {
1811                                             if (p2 != VDEC_S_SUCCESS) {
1812                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1813                                                 pThis->omx_report_error ();
1814                                             } else {
1815                                                 pThis->complete_pending_buffer_done_cbs();
1816                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1817                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
1818                                                     // Send the callback now
1819                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1820                                                     pThis->m_state = OMX_StateIdle;
1821                                                     DEBUG_PRINT_LOW("Move to Idle State");
1822                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1823                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
1824                                                             OMX_StateIdle,NULL);
1825                                                 }
1826                                             }
1827                                         } else {
1828                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1829                                         }
1830 
1831                                         break;
1832 
1833                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1834                                         if (p2 == OMX_IndexParamPortDefinition) {
1835                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
1836                                             pThis->in_reconfig = true;
1837                                             pThis->prev_n_filled_len = 0;
1838                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1839                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
1840 
1841                                             /* Check if resolution is changed in smooth streaming mode */
1842                                             if (pThis->m_smoothstreaming_mode &&
1843                                                 (pThis->framesize.nWidth !=
1844                                                     pThis->drv_ctx.video_resolution.frame_width) ||
1845                                                 (pThis->framesize.nHeight !=
1846                                                     pThis->drv_ctx.video_resolution.frame_height)) {
1847 
1848                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1849                                                         pThis->framesize.nWidth,
1850                                                         pThis->framesize.nHeight,
1851                                                         pThis->drv_ctx.video_resolution.frame_width,
1852                                                         pThis->drv_ctx.video_resolution.frame_height);
1853 
1854                                                 /* Update new resolution */
1855                                                 pThis->framesize.nWidth =
1856                                                        pThis->drv_ctx.video_resolution.frame_width;
1857                                                 pThis->framesize.nHeight =
1858                                                        pThis->drv_ctx.video_resolution.frame_height;
1859 
1860                                                 /* Update C2D with new resolution */
1861                                                 if (!pThis->client_buffers.update_buffer_req()) {
1862                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1863                                                 }
1864                                             }
1865 
1866                                             /* Update new crop information */
1867                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1868                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1869                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1870                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1871 
1872                                             /* Validate the new crop information */
1873                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1874                                                 pThis->drv_ctx.video_resolution.frame_width) {
1875 
1876                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1877                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1878                                                         pThis->drv_ctx.video_resolution.frame_width);
1879                                                 pThis->rectangle.nLeft = 0;
1880 
1881                                                 if (pThis->rectangle.nWidth >
1882                                                     pThis->drv_ctx.video_resolution.frame_width) {
1883 
1884                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1885                                                             pThis->rectangle.nWidth,
1886                                                             pThis->drv_ctx.video_resolution.frame_width);
1887                                                     pThis->rectangle.nWidth =
1888                                                         pThis->drv_ctx.video_resolution.frame_width;
1889                                                 }
1890                                             }
1891                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1892                                                 pThis->drv_ctx.video_resolution.frame_height) {
1893 
1894                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1895                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
1896                                                     pThis->drv_ctx.video_resolution.frame_height);
1897                                                 pThis->rectangle.nTop = 0;
1898 
1899                                                 if (pThis->rectangle.nHeight >
1900                                                     pThis->drv_ctx.video_resolution.frame_height) {
1901 
1902                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1903                                                         pThis->rectangle.nHeight,
1904                                                         pThis->drv_ctx.video_resolution.frame_height);
1905                                                     pThis->rectangle.nHeight =
1906                                                         pThis->drv_ctx.video_resolution.frame_height;
1907                                                 }
1908                                             }
1909                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1910                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
1911                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1912                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
1913                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
1914                                         } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) {
1915                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo");
1916                                         } else {
1917                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1918                                             break;
1919                                         }
1920                                         if (pThis->m_debug.outfile) {
1921                                             fclose(pThis->m_debug.outfile);
1922                                             pThis->m_debug.outfile = NULL;
1923                                         }
1924                                         if (pThis->m_debug.ccoutfile) {
1925                                             fclose(pThis->m_debug.ccoutfile);
1926                                             pThis->m_debug.ccoutfile = NULL;
1927                                         }
1928                                         if (pThis->m_debug.out_ymeta_file) {
1929                                             fclose(pThis->m_debug.out_ymeta_file);
1930                                             pThis->m_debug.out_ymeta_file = NULL;
1931                                         }
1932                                         if (pThis->m_debug.out_uvmeta_file) {
1933                                             fclose(pThis->m_debug.out_uvmeta_file);
1934                                             pThis->m_debug.out_uvmeta_file = NULL;
1935                                         }
1936                                         pThis->m_debug.seq_count++;
1937 
1938                                         if (pThis->m_cb.EventHandler) {
1939                                             void *frame_data = NULL;
1940                                             reconfig_client_data port_data;
1941                                             reconfig_client_crop_data crop_data;
1942                                             if (p2 == OMX_IndexConfigCommonOutputCrop) {
1943                                                 crop_data.width = pThis->rectangle.nWidth;
1944                                                 crop_data.height = pThis->rectangle.nHeight;
1945                                                 crop_data.left = pThis->rectangle.nLeft;
1946                                                 crop_data.top = pThis->rectangle.nTop;
1947                                                 crop_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1948                                                 frame_data = (void*)&crop_data;
1949                                             } else if (p2 == OMX_IndexParamPortDefinition){
1950                                                 port_data.width = pThis->m_reconfig_width;
1951                                                 port_data.height = pThis->m_reconfig_height;
1952                                                 port_data.dpb_bit_depth = pThis->dpb_bit_depth;
1953                                                 port_data.m_progressive = pThis->m_progressive;
1954                                                 port_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1955                                                 frame_data = (void*)&port_data;
1956                                             }
1957                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1958                                                      OMX_EventPortSettingsChanged, p1, p2, (void*)frame_data);
1959                                         } else {
1960                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1961                                         }
1962                                         break;
1963 
1964                 case OMX_COMPONENT_GENERATE_EOS_DONE:
1965                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1966                                         if (pThis->m_cb.EventHandler) {
1967                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1968                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1969                                         } else {
1970                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1971                                         }
1972                                         pThis->prev_ts = LLONG_MAX;
1973                                         pThis->rst_prev_ts = true;
1974                                         break;
1975 
1976                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1977                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1978                                         pThis->omx_report_error();
1979                                         break;
1980 
1981                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1982                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
1983                                         pThis->omx_report_unsupported_setting();
1984                                         break;
1985 
1986                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1987                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1988                                         pThis->omx_report_hw_overload();
1989                                         break;
1990 
1991                 case OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL:
1992                                         DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL");
1993                                         pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_PIXEL);
1994                                         break;
1995 
1996                 case OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL:
1997                                         DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL");
1998                                         pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_NON_PIXEL) << 1;
1999                                         break;
2000 
2001                 default:
2002                                         break;
2003             }
2004         }
2005         pthread_mutex_lock(&pThis->m_lock);
2006         qsize = pThis->m_cmd_q.m_size;
2007         if (pThis->m_state != OMX_StatePause)
2008             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
2009         pthread_mutex_unlock(&pThis->m_lock);
2010     } while (qsize>0);
2011 
2012 }
2013 
update_resolution(int width,int height,int stride,int scan_lines)2014 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
2015 {
2016     int format_changed = 0;
2017     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
2018             (width != (int)drv_ctx.video_resolution.frame_width)) {
2019         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
2020                 width, drv_ctx.video_resolution.frame_width,
2021                 height,drv_ctx.video_resolution.frame_height);
2022         format_changed = 1;
2023     }
2024     drv_ctx.video_resolution.frame_height = height;
2025     drv_ctx.video_resolution.frame_width = width;
2026     drv_ctx.video_resolution.scan_lines = scan_lines;
2027     drv_ctx.video_resolution.stride = stride;
2028 
2029     if (!is_down_scalar_enabled) {
2030         rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft;
2031         rectangle.nTop = m_extradata_info.output_crop_rect.nTop;
2032         rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth;
2033         rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight;
2034     }
2035     return format_changed;
2036 }
2037 
log_input_buffers(const char * buffer_addr,int buffer_len,uint64_t timeStamp,int fd)2038 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len, uint64_t timeStamp, int fd)
2039 {
2040     if (!m_debug.in_buffer_log)
2041         return 0;
2042 
2043 #ifdef USE_ION
2044     do_cache_operations(fd);
2045 #else
2046     (void)fd;
2047 #endif
2048     if (m_debug.in_buffer_log && !m_debug.infile) {
2049         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
2050                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p_%" PRId64 ".mpg", m_debug.log_loc,
2051                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this, m_debug.session_id);
2052         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
2053                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
2054                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
2055                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2056         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
2057                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
2058                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2059         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
2060                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2061                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2062         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2063                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2064                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2065         } else {
2066                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.bin",
2067                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2068         }
2069         m_debug.infile = fopen (m_debug.infile_name, "ab");
2070         if (!m_debug.infile) {
2071             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging (%d:%s)",
2072                              m_debug.infile_name, errno, strerror(errno));
2073             m_debug.infile_name[0] = '\0';
2074 #ifdef USE_ION
2075             do_cache_operations(fd);
2076 #endif
2077             return -1;
2078         }
2079         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2080                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2081             bool isVp9 = drv_ctx.decoder_format == VDEC_CODECTYPE_VP9;
2082             int width = drv_ctx.video_resolution.frame_width;
2083             int height = drv_ctx.video_resolution.frame_height;
2084             int fps = drv_ctx.frame_rate.fps_numerator;
2085             IvfFileHeader ivfHeader(isVp9, width, height, 1, fps, 0);
2086             fwrite((const char *)&ivfHeader,
2087                     sizeof(ivfHeader),1,m_debug.infile);
2088          }
2089     }
2090     if (m_debug.infile && buffer_addr && buffer_len) {
2091         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2092                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2093             IvfFrameHeader ivfFrameHeader(buffer_len, timeStamp);
2094             fwrite(&ivfFrameHeader, sizeof(ivfFrameHeader), 1, m_debug.infile);
2095         }
2096         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
2097     }
2098 #ifdef USE_ION
2099     do_cache_operations(fd);
2100 #endif
2101     return 0;
2102 }
2103 
log_cc_output_buffers(OMX_BUFFERHEADERTYPE * buffer)2104 int omx_vdec::log_cc_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2105     if (client_buffers.client_buffers_invalid() ||
2106         !m_debug.out_cc_buffer_log || !buffer || !buffer->nFilledLen)
2107         return 0;
2108 
2109     if (m_debug.out_cc_buffer_log && !m_debug.ccoutfile) {
2110         snprintf(m_debug.ccoutfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_cc_%d_%d_%p_%" PRId64 "_%d.yuv",
2111                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2112                 m_debug.session_id, m_debug.seq_count);
2113         m_debug.ccoutfile = fopen (m_debug.ccoutfile_name, "ab");
2114         if (!m_debug.ccoutfile) {
2115             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2116             m_debug.ccoutfile_name[0] = '\0';
2117             return -1;
2118         }
2119         DEBUG_PRINT_HIGH("Opened CC output file: %s for logging", m_debug.ccoutfile_name);
2120     }
2121 
2122     fwrite(buffer->pBuffer, buffer->nFilledLen, 1, m_debug.ccoutfile);
2123     return 0;
2124 }
2125 
log_output_buffers(OMX_BUFFERHEADERTYPE * buffer)2126 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2127     int buf_index = 0;
2128     char *temp = NULL;
2129     char *bufaddr = NULL;
2130 
2131     if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
2132         return 0;
2133 
2134     if (m_debug.out_buffer_log && !m_debug.outfile) {
2135         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p_%" PRId64 "_%d.yuv",
2136                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2137                 m_debug.session_id, m_debug.seq_count);
2138         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
2139         if (!m_debug.outfile) {
2140             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2141             m_debug.outfile_name[0] = '\0';
2142             return -1;
2143         }
2144         DEBUG_PRINT_HIGH("Opened output file: %s for logging", m_debug.outfile_name);
2145     }
2146 
2147     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) {
2148         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
2149                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2150         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
2151                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2152         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
2153         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
2154         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
2155             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
2156             m_debug.out_ymetafile_name[0] = '\0';
2157             m_debug.out_uvmetafile_name[0] = '\0';
2158             return -1;
2159         }
2160     }
2161 
2162     buf_index = buffer - m_out_mem_ptr;
2163     bufaddr = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
2164     if (dynamic_buf_mode && !secure_mode) {
2165         bufaddr = ion_map(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd,
2166                           drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2167         //mmap returns (void *)-1 on failure and sets error code in errno.
2168         if (bufaddr == MAP_FAILED) {
2169             DEBUG_PRINT_ERROR("mmap failed - errno: %d", errno);
2170             return -1;
2171         }
2172     }
2173     temp = bufaddr;
2174 
2175     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
2176             drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
2177         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
2178             drv_ctx.video_resolution.frame_width,
2179             drv_ctx.video_resolution.frame_height);
2180 
2181         if (m_debug.outfile)
2182             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
2183 
2184         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
2185             unsigned int width = 0, height = 0;
2186             unsigned int y_plane, y_meta_plane;
2187             int y_stride = 0, y_sclines = 0;
2188             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
2189             int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC;
2190             int i;
2191             int bytes_written = 0;
2192 
2193             width = drv_ctx.video_resolution.frame_width;
2194             height = drv_ctx.video_resolution.frame_height;
2195             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
2196             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
2197             y_stride = VENUS_Y_STRIDE(color_fmt, width);
2198             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
2199             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
2200             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
2201 
2202             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
2203             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
2204 
2205             for (i = 0; i < y_meta_scanlines; i++) {
2206                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
2207                  temp += y_meta_stride;
2208             }
2209 
2210             temp = bufaddr + y_meta_plane + y_plane;
2211             for(i = 0; i < uv_meta_scanlines; i++) {
2212                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
2213                 temp += uv_meta_stride;
2214             }
2215         }
2216     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
2217         int stride = drv_ctx.video_resolution.stride;
2218         int scanlines = drv_ctx.video_resolution.scan_lines;
2219         if (m_smoothstreaming_mode) {
2220             stride = drv_ctx.video_resolution.frame_width;
2221             scanlines = drv_ctx.video_resolution.frame_height;
2222             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2223             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2224         }
2225         unsigned i;
2226         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2227             drv_ctx.video_resolution.frame_width,
2228             drv_ctx.video_resolution.frame_height, stride, scanlines);
2229         int bytes_written = 0;
2230         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2231              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2232              temp += stride;
2233         }
2234         temp = bufaddr + stride * scanlines;
2235         int stride_c = stride;
2236         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2237             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2238             temp += stride_c;
2239         }
2240     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
2241         int stride = drv_ctx.video_resolution.stride;
2242         int scanlines = drv_ctx.video_resolution.scan_lines;
2243         if (m_smoothstreaming_mode) {
2244             stride = drv_ctx.video_resolution.frame_width * 2;
2245             scanlines = drv_ctx.video_resolution.frame_height;
2246             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2247             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2248         }
2249         unsigned i;
2250         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2251             drv_ctx.video_resolution.frame_width,
2252             drv_ctx.video_resolution.frame_height, stride, scanlines);
2253         int bytes_written = 0;
2254         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2255              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2256              temp += stride;
2257         }
2258         temp = bufaddr + stride * scanlines;
2259         int stride_c = stride;
2260         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2261             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2262             temp += stride_c;
2263         }
2264     }
2265 
2266     if (dynamic_buf_mode && !secure_mode) {
2267         ion_unmap(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, bufaddr,
2268                   drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2269     }
2270     return 0;
2271 }
2272 
init_color_aspects_map()2273 void omx_vdec::init_color_aspects_map()
2274 {
2275     mPrimariesMap.insert({
2276             {ColorAspects::PrimariesUnspecified, (ColorPrimaries)(2)},
2277             {ColorAspects::PrimariesBT709_5, ColorPrimaries_BT709_5},
2278             {ColorAspects::PrimariesBT470_6M, ColorPrimaries_BT470_6M},
2279             {ColorAspects::PrimariesBT601_6_625, ColorPrimaries_BT601_6_625},
2280             {ColorAspects::PrimariesBT601_6_525, ColorPrimaries_BT601_6_525},
2281             {ColorAspects::PrimariesGenericFilm, ColorPrimaries_GenericFilm},
2282             {ColorAspects::PrimariesBT2020, ColorPrimaries_BT2020},
2283         });
2284     mTransferMap.insert({
2285             {ColorAspects::TransferUnspecified, (GammaTransfer)(2)},
2286             {ColorAspects::TransferLinear, Transfer_Linear},
2287             {ColorAspects::TransferSRGB, Transfer_sRGB},
2288             {ColorAspects::TransferSMPTE170M, Transfer_SMPTE_170M},
2289             {ColorAspects::TransferGamma22, Transfer_Gamma2_2},
2290             {ColorAspects::TransferGamma28, Transfer_Gamma2_8},
2291             {ColorAspects::TransferST2084, Transfer_SMPTE_ST2084},
2292             {ColorAspects::TransferHLG, Transfer_HLG},
2293             {ColorAspects::TransferSMPTE240M, Transfer_SMPTE_240M},
2294             {ColorAspects::TransferXvYCC, Transfer_XvYCC},
2295             {ColorAspects::TransferBT1361, Transfer_BT1361},
2296             {ColorAspects::TransferST428, Transfer_ST_428},
2297         });
2298     mMatrixCoeffMap.insert({
2299             {ColorAspects::MatrixUnspecified, (MatrixCoEfficients)(2)},
2300             {ColorAspects::MatrixBT709_5, MatrixCoEff_BT709_5},
2301             {ColorAspects::MatrixBT470_6M, MatrixCoeff_FCC_73_682},
2302             {ColorAspects::MatrixBT601_6, MatrixCoEff_BT601_6_625},
2303             {ColorAspects::MatrixSMPTE240M, MatrixCoEff_SMPTE240M},
2304             {ColorAspects::MatrixBT2020, MatrixCoEff_BT2020},
2305             {ColorAspects::MatrixBT2020Constant, MatrixCoEff_BT2020Constant},
2306         });
2307     mColorRangeMap.insert({
2308             {ColorAspects::RangeUnspecified, (ColorRange)(2)},
2309             {ColorAspects::RangeFull, Range_Full},
2310             {ColorAspects::RangeLimited, Range_Limited},
2311         });
2312 }
2313 /* ======================================================================
2314    FUNCTION
2315    omx_vdec::ComponentInit
2316 
2317    DESCRIPTION
2318    Initialize the component.
2319 
2320    PARAMETERS
2321    ctxt -- Context information related to the self.
2322    id   -- Event identifier. This could be any of the following:
2323    1. Command completion event
2324    2. Buffer done callback event
2325    3. Frame done callback event
2326 
2327    RETURN VALUE
2328    None.
2329 
2330    ========================================================================== */
component_init(OMX_STRING role)2331 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
2332 {
2333 
2334     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2335     struct v4l2_fmtdesc fdesc;
2336     struct v4l2_format fmt;
2337     struct v4l2_requestbuffers bufreq;
2338     struct v4l2_control control;
2339     struct v4l2_frmsizeenum frmsize;
2340     struct v4l2_queryctrl query;
2341     unsigned int   alignment = 0,buffer_size = 0;
2342     int fds[2];
2343     int r,ret=0;
2344     bool codec_ambiguous = false;
2345     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
2346     char property_value[PROPERTY_VALUE_MAX] = {0};
2347     FILE *soc_file = NULL;
2348     char buffer[10];
2349     struct v4l2_ext_control ctrl[2];
2350     struct v4l2_ext_controls controls;
2351     int conceal_color_8bit = 0, conceal_color_10bit = 0;
2352 
2353 #ifdef _ANDROID_
2354     char platform_name[PROPERTY_VALUE_MAX];
2355     property_get("ro.board.platform", platform_name, "0");
2356     if (!strncmp(platform_name, "msm8610", 7)) {
2357         device_name = (OMX_STRING)"/dev/video/q6_dec";
2358         is_q6_platform = true;
2359         maxSmoothStreamingWidth = 1280;
2360         maxSmoothStreamingHeight = 720;
2361     }
2362 #endif
2363 
2364     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
2365                 OMX_MAX_STRINGNAME_SIZE)) {
2366         secure_mode = true;
2367         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
2368     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
2369                 OMX_MAX_STRINGNAME_SIZE)) {
2370         secure_mode = true;
2371         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
2372     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
2373                 OMX_MAX_STRINGNAME_SIZE)) {
2374         secure_mode = true;
2375         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
2376     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
2377                 OMX_MAX_STRINGNAME_SIZE)) {
2378         secure_mode = true;
2379         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
2380     }
2381 
2382 #ifdef HYPERVISOR
2383     drv_ctx.video_driver_fd = hypv_open(device_name, O_RDWR);
2384 #else
2385     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
2386 #endif
2387 
2388     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
2389 
2390     if (drv_ctx.video_driver_fd < 0) {
2391         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
2392         return OMX_ErrorInsufficientResources;
2393     }
2394     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
2395     drv_ctx.frame_rate.fps_denominator = 1;
2396     operating_frame_rate = DEFAULT_FPS;
2397     m_poll_efd = eventfd(0, 0);
2398     if (m_poll_efd < 0) {
2399         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
2400         return OMX_ErrorInsufficientResources;
2401     }
2402     ret = subscribe_to_events(drv_ctx.video_driver_fd);
2403     if (!ret) {
2404         async_thread_created = true;
2405         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
2406     }
2407     if (ret) {
2408         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
2409         async_thread_created = false;
2410         return OMX_ErrorInsufficientResources;
2411     }
2412 
2413 #ifdef OUTPUT_EXTRADATA_LOG
2414     outputExtradataFile = fopen (output_extradata_filename, "ab");
2415 #endif
2416 
2417     // Copy the role information which provides the decoder kind
2418     strlcpy(drv_ctx.kind,role,128);
2419 
2420 
2421     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
2422                 OMX_MAX_STRINGNAME_SIZE)) {
2423         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
2424                 OMX_MAX_STRINGNAME_SIZE);
2425         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
2426         output_capability = V4L2_PIX_FMT_MPEG2;
2427         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
2428         /*Initialize Start Code for MPEG2*/
2429         codec_type_parse = CODEC_TYPE_MPEG2;
2430         m_frame_parser.init_start_codes(codec_type_parse);
2431     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
2432                 OMX_MAX_STRINGNAME_SIZE)) {
2433         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2434         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
2435         output_capability=V4L2_PIX_FMT_H264;
2436         eCompressionFormat = OMX_VIDEO_CodingAVC;
2437         codec_type_parse = CODEC_TYPE_H264;
2438         m_frame_parser.init_start_codes(codec_type_parse);
2439         m_frame_parser.init_nal_length(nal_length);
2440     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
2441                 OMX_MAX_STRINGNAME_SIZE)) {
2442         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
2443         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
2444         output_capability = V4L2_PIX_FMT_H264_MVC;
2445         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
2446         codec_type_parse = CODEC_TYPE_H264;
2447         m_frame_parser.init_start_codes(codec_type_parse);
2448         m_frame_parser.init_nal_length(nal_length);
2449     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
2450                 OMX_MAX_STRINGNAME_SIZE)) {
2451         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
2452         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
2453         output_capability = V4L2_PIX_FMT_HEVC;
2454         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
2455         codec_type_parse = CODEC_TYPE_HEVC;
2456         m_frame_parser.init_start_codes(codec_type_parse);
2457         m_frame_parser.init_nal_length(nal_length);
2458     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
2459                 OMX_MAX_STRINGNAME_SIZE)) {
2460         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
2461         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
2462         output_capability = V4L2_PIX_FMT_VP8;
2463         eCompressionFormat = OMX_VIDEO_CodingVP8;
2464         codec_type_parse = CODEC_TYPE_VP8;
2465     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
2466                 OMX_MAX_STRINGNAME_SIZE)) {
2467         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
2468         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
2469         output_capability = V4L2_PIX_FMT_VP9;
2470         eCompressionFormat = OMX_VIDEO_CodingVP9;
2471         codec_type_parse = CODEC_TYPE_VP9;
2472     } else {
2473         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
2474         eRet = OMX_ErrorInvalidComponentName;
2475     }
2476 
2477     m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
2478 
2479     if (eRet == OMX_ErrorNone) {
2480         OMX_COLOR_FORMATTYPE dest_color_format;
2481         if (m_disable_ubwc_mode) {
2482             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
2483         } else {
2484             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
2485         }
2486         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
2487             dest_color_format = (OMX_COLOR_FORMATTYPE)
2488                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
2489         else
2490             dest_color_format = (OMX_COLOR_FORMATTYPE)
2491                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2492         if (!client_buffers.set_color_format(dest_color_format)) {
2493             DEBUG_PRINT_ERROR("Setting color format failed");
2494             eRet = OMX_ErrorInsufficientResources;
2495         }
2496 
2497         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
2498         is_flexible_format = FALSE;
2499         is_mbaff = FALSE;
2500 
2501         if (m_disable_ubwc_mode) {
2502             capture_capability = V4L2_PIX_FMT_NV12;
2503         } else {
2504             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
2505         }
2506 
2507         struct v4l2_capability cap;
2508         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
2509         if (ret) {
2510             DEBUG_PRINT_ERROR("Failed to query capabilities");
2511             /*TODO: How to handle this case */
2512         } else {
2513             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
2514                 " version = %d, capabilities = %x", cap.driver, cap.card,
2515                 cap.bus_info, cap.version, cap.capabilities);
2516         }
2517         ret=0;
2518         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2519         fdesc.index=0;
2520         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2521             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2522                     fdesc.pixelformat, fdesc.flags);
2523             fdesc.index++;
2524         }
2525         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2526         fdesc.index=0;
2527         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2528 
2529             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2530                     fdesc.pixelformat, fdesc.flags);
2531             fdesc.index++;
2532         }
2533         m_extradata_info.output_crop_rect.nLeft = 0;
2534         m_extradata_info.output_crop_rect.nTop = 0;
2535         m_extradata_info.output_crop_rect.nWidth = 320;
2536         m_extradata_info.output_crop_rect.nHeight = 240;
2537         update_resolution(320, 240, 320, 240);
2538 
2539         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2540         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2541         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2542         fmt.fmt.pix_mp.pixelformat = output_capability;
2543         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2544         if (ret) {
2545             /*TODO: How to handle this case */
2546             DEBUG_PRINT_ERROR("Failed to set format on output port");
2547             return OMX_ErrorInsufficientResources;
2548         }
2549         DEBUG_PRINT_HIGH("Set Format was successful");
2550 
2551         /*
2552          * refer macro DEFAULT_CONCEAL_COLOR to set conceal color values
2553          */
2554         Platform::Config::getInt32(Platform::vidc_dec_conceal_color_8bit, &conceal_color_8bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2555         Platform::Config::getInt32(Platform::vidc_dec_conceal_color_10bit, &conceal_color_10bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2556         memset(&controls, 0, sizeof(controls));
2557         memset(ctrl, 0, sizeof(ctrl));
2558         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT;
2559         ctrl[0].value = conceal_color_8bit;
2560         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT;
2561         ctrl[1].value = conceal_color_10bit;
2562 
2563         controls.count = 2;
2564         controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
2565         controls.controls = ctrl;
2566         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
2567         if (ret) {
2568             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
2569         }
2570 
2571         //Get the hardware capabilities
2572         memset((void *)&frmsize,0,sizeof(frmsize));
2573         frmsize.index = 0;
2574         frmsize.pixel_format = output_capability;
2575         ret = ioctl(drv_ctx.video_driver_fd,
2576                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
2577         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
2578             DEBUG_PRINT_ERROR("Failed to get framesizes");
2579             return OMX_ErrorHardware;
2580         }
2581 
2582         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
2583             m_decoder_capability.min_width = frmsize.stepwise.min_width;
2584             m_decoder_capability.max_width = frmsize.stepwise.max_width;
2585             m_decoder_capability.min_height = frmsize.stepwise.min_height;
2586             m_decoder_capability.max_height = frmsize.stepwise.max_height;
2587         }
2588 
2589         /* Based on UBWC enable, decide split mode to driver before calling S_FMT */
2590         eRet = set_dpb(m_disable_ubwc_mode);
2591 
2592         memset(&fmt, 0x0, sizeof(struct v4l2_format));
2593         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2594         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2595         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2596         fmt.fmt.pix_mp.pixelformat = capture_capability;
2597         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2598         if (ret) {
2599             /*TODO: How to handle this case */
2600             DEBUG_PRINT_ERROR("Failed to set format on capture port");
2601         }
2602         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
2603         framesize.nWidth = drv_ctx.video_resolution.frame_width;
2604         framesize.nHeight = drv_ctx.video_resolution.frame_height;
2605 
2606         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
2607         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
2608         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
2609 
2610         DEBUG_PRINT_HIGH("Set Format was successful");
2611         if (secure_mode) {
2612             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
2613             control.value = 1;
2614             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
2615             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2616             if (ret) {
2617                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
2618                 return OMX_ErrorInsufficientResources;
2619             }
2620         }
2621 
2622         /*Get the Buffer requirements for input and output ports*/
2623         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
2624         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2625 
2626         if (secure_mode) {
2627             drv_ctx.op_buf.alignment = SECURE_ALIGN;
2628             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
2629         } else {
2630             drv_ctx.op_buf.alignment = SZ_4K;
2631             drv_ctx.ip_buf.alignment = SZ_4K;
2632         }
2633 
2634         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
2635         drv_ctx.extradata = 0;
2636         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
2637         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
2638         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
2639         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
2640         drv_ctx.idr_only_decoding = 0;
2641 
2642 #ifdef _ANDROID_
2643         if (m_dec_hfr_fps) {
2644             memset(&query, 0, sizeof(struct v4l2_queryctrl));
2645 
2646             query.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
2647             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &query);
2648             if (!ret)
2649                 m_dec_hfr_fps = MIN(query.maximum, m_dec_hfr_fps);
2650 
2651             DEBUG_PRINT_HIGH("Updated HFR fps value = %d", m_dec_hfr_fps);
2652         }
2653 
2654 #endif
2655         m_state = OMX_StateLoaded;
2656 
2657         unsigned long long extradata_mask = DEFAULT_EXTRADATA;
2658         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc) {
2659             extradata_mask |= OMX_HDR_COLOR_INFO_EXTRADATA | OMX_EXTNUSER_EXTRADATA;
2660         }
2661         enable_extradata(extradata_mask, true, true);
2662 
2663         eRet = get_buffer_req(&drv_ctx.ip_buf);
2664         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
2665         get_buffer_req(&drv_ctx.op_buf);
2666         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2667                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
2668                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2669                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
2670                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
2671                     h264_scratch.nFilledLen = 0;
2672                     h264_scratch.nOffset = 0;
2673 
2674                     if (h264_scratch.pBuffer == NULL) {
2675                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
2676                         return OMX_ErrorInsufficientResources;
2677                     }
2678         }
2679         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2680             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2681             if (m_frame_parser.mutils == NULL) {
2682                 m_frame_parser.mutils = new H264_Utils();
2683                 if (m_frame_parser.mutils == NULL) {
2684                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
2685                     eRet = OMX_ErrorInsufficientResources;
2686                 } else {
2687                     m_frame_parser.mutils->initialize_frame_checking_environment();
2688                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
2689                 }
2690             }
2691 
2692             h264_parser = new h264_stream_parser();
2693             if (!h264_parser) {
2694                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
2695                 eRet = OMX_ErrorInsufficientResources;
2696             }
2697         }
2698         msg_thread_created = true;
2699         r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
2700 
2701         if (r < 0) {
2702             DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
2703             msg_thread_created = false;
2704             eRet = OMX_ErrorInsufficientResources;
2705         } else if (secure_mode) {
2706             this->post_event(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL);
2707             this->post_event(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL);
2708         }
2709     }
2710 
2711     {
2712         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
2713         init_vendor_extensions(*extStore);
2714         mVendorExtensionStore.dumpExtensions((const char *)role);
2715     }
2716 
2717     if (eRet != OMX_ErrorNone) {
2718         DEBUG_PRINT_ERROR("Component Init Failed");
2719     } else {
2720         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
2721                 drv_ctx.video_driver_fd);
2722     }
2723     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
2724 
2725     OMX_INIT_STRUCT(&m_sParamLowLatency, QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE);
2726     m_sParamLowLatency.nNumFrames = 0;
2727     m_sParamLowLatency.bEnableLowLatencyMode = OMX_FALSE;
2728 
2729     return eRet;
2730 }
2731 
2732 /* ======================================================================
2733    FUNCTION
2734    omx_vdec::GetComponentVersion
2735 
2736    DESCRIPTION
2737    Returns the component version.
2738 
2739    PARAMETERS
2740    TBD.
2741 
2742    RETURN VALUE
2743    OMX_ErrorNone.
2744 
2745    ========================================================================== */
get_component_version(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STRING componentName,OMX_OUT OMX_VERSIONTYPE * componentVersion,OMX_OUT OMX_VERSIONTYPE * specVersion,OMX_OUT OMX_UUIDTYPE * componentUUID)2746 OMX_ERRORTYPE  omx_vdec::get_component_version
2747 (
2748  OMX_IN OMX_HANDLETYPE hComp,
2749  OMX_OUT OMX_STRING componentName,
2750  OMX_OUT OMX_VERSIONTYPE* componentVersion,
2751  OMX_OUT OMX_VERSIONTYPE* specVersion,
2752  OMX_OUT OMX_UUIDTYPE* componentUUID
2753  )
2754 {
2755     (void) hComp;
2756     (void) componentName;
2757     (void) componentVersion;
2758     (void) componentUUID;
2759     if (m_state == OMX_StateInvalid) {
2760         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
2761         return OMX_ErrorInvalidState;
2762     }
2763     /* TBD -- Return the proper version */
2764     if (specVersion) {
2765         specVersion->nVersion = OMX_SPEC_VERSION;
2766     }
2767     return OMX_ErrorNone;
2768 }
2769 /* ======================================================================
2770    FUNCTION
2771    omx_vdec::SendCommand
2772 
2773    DESCRIPTION
2774    Returns zero if all the buffers released..
2775 
2776    PARAMETERS
2777    None.
2778 
2779    RETURN VALUE
2780    true/false
2781 
2782    ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)2783 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
2784         OMX_IN OMX_COMMANDTYPE cmd,
2785         OMX_IN OMX_U32 param1,
2786         OMX_IN OMX_PTR cmdData
2787         )
2788 {
2789     (void) hComp;
2790     (void) cmdData;
2791     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
2792     if (m_state == OMX_StateInvalid) {
2793         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
2794         return OMX_ErrorInvalidState;
2795     }
2796     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
2797             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
2798         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
2799                 "to invalid port: %u", (unsigned int)param1);
2800         return OMX_ErrorBadPortIndex;
2801     }
2802 
2803     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2804     sem_wait(&m_cmd_lock);
2805     DEBUG_PRINT_LOW("send_command: Command Processed");
2806     return OMX_ErrorNone;
2807 }
2808 
2809 /* ======================================================================
2810    FUNCTION
2811    omx_vdec::SendCommand
2812 
2813    DESCRIPTION
2814    Returns zero if all the buffers released..
2815 
2816    PARAMETERS
2817    None.
2818 
2819    RETURN VALUE
2820    true/false
2821 
2822    ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)2823 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
2824         OMX_IN OMX_COMMANDTYPE cmd,
2825         OMX_IN OMX_U32 param1,
2826         OMX_IN OMX_PTR cmdData
2827         )
2828 {
2829     (void) hComp;
2830     (void) cmdData;
2831     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2832     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2833     int bFlag = 1,sem_posted = 0,ret=0;
2834 
2835     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2836     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
2837             m_state, eState);
2838 
2839     if (cmd == OMX_CommandStateSet) {
2840         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2841         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
2842         /***************************/
2843         /* Current State is Loaded */
2844         /***************************/
2845         if (m_state == OMX_StateLoaded) {
2846             if (eState == OMX_StateIdle) {
2847                 //if all buffers are allocated or all ports disabled
2848                 if (allocate_done() ||
2849                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
2850                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
2851                 } else {
2852                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
2853                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2854                     // Skip the event notification
2855                     bFlag = 0;
2856                 }
2857             }
2858             /* Requesting transition from Loaded to Loaded */
2859             else if (eState == OMX_StateLoaded) {
2860                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
2861                 post_event(OMX_EventError,OMX_ErrorSameState,\
2862                         OMX_COMPONENT_GENERATE_EVENT);
2863                 eRet = OMX_ErrorSameState;
2864             }
2865             /* Requesting transition from Loaded to WaitForResources */
2866             else if (eState == OMX_StateWaitForResources) {
2867                 /* Since error is None , we will post an event
2868                    at the end of this function definition */
2869                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
2870             }
2871             /* Requesting transition from Loaded to Executing */
2872             else if (eState == OMX_StateExecuting) {
2873                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
2874                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2875                         OMX_COMPONENT_GENERATE_EVENT);
2876                 eRet = OMX_ErrorIncorrectStateTransition;
2877             }
2878             /* Requesting transition from Loaded to Pause */
2879             else if (eState == OMX_StatePause) {
2880                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
2881                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2882                         OMX_COMPONENT_GENERATE_EVENT);
2883                 eRet = OMX_ErrorIncorrectStateTransition;
2884             }
2885             /* Requesting transition from Loaded to Invalid */
2886             else if (eState == OMX_StateInvalid) {
2887                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
2888                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2889                 eRet = OMX_ErrorInvalidState;
2890             } else {
2891                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
2892                         eState);
2893                 eRet = OMX_ErrorBadParameter;
2894             }
2895         }
2896 
2897         /***************************/
2898         /* Current State is IDLE */
2899         /***************************/
2900         else if (m_state == OMX_StateIdle) {
2901             if (eState == OMX_StateLoaded) {
2902                 if (release_done()) {
2903                     /*
2904                      * Since error is None , we will post an event at the end
2905                      * of this function definition
2906                      * Reset buffer requirements here to ensure setting buffer requirement
2907                      * when component move to executing state from loaded state via Idle.
2908                      */
2909                     drv_ctx.op_buf.buffer_size = 0;
2910                     drv_ctx.op_buf.actualcount = 0;
2911                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
2912                 } else {
2913                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
2914                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2915                     // Skip the event notification
2916                     bFlag = 0;
2917                 }
2918             }
2919             /* Requesting transition from Idle to Executing */
2920             else if (eState == OMX_StateExecuting) {
2921                 bFlag = 1;
2922                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2923                 m_state=OMX_StateExecuting;
2924             }
2925             /* Requesting transition from Idle to Idle */
2926             else if (eState == OMX_StateIdle) {
2927                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
2928                 post_event(OMX_EventError,OMX_ErrorSameState,\
2929                         OMX_COMPONENT_GENERATE_EVENT);
2930                 eRet = OMX_ErrorSameState;
2931             }
2932             /* Requesting transition from Idle to WaitForResources */
2933             else if (eState == OMX_StateWaitForResources) {
2934                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
2935                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2936                         OMX_COMPONENT_GENERATE_EVENT);
2937                 eRet = OMX_ErrorIncorrectStateTransition;
2938             }
2939             /* Requesting transition from Idle to Pause */
2940             else if (eState == OMX_StatePause) {
2941                 /*To pause the Video core we need to start the driver*/
2942                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2943                       NULL) < */0) {
2944                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
2945                     omx_report_error ();
2946                     eRet = OMX_ErrorHardware;
2947                 } else {
2948                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2949                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
2950                     bFlag = 0;
2951                 }
2952             }
2953             /* Requesting transition from Idle to Invalid */
2954             else if (eState == OMX_StateInvalid) {
2955                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
2956                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2957                 eRet = OMX_ErrorInvalidState;
2958             } else {
2959                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
2960                 eRet = OMX_ErrorBadParameter;
2961             }
2962         }
2963 
2964         /******************************/
2965         /* Current State is Executing */
2966         /******************************/
2967         else if (m_state == OMX_StateExecuting) {
2968             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
2969             /* Requesting transition from Executing to Idle */
2970             if (eState == OMX_StateIdle) {
2971                 /* Since error is None , we will post an event
2972                    at the end of this function definition
2973                  */
2974                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
2975                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2976                 if (!sem_posted) {
2977                     sem_posted = 1;
2978                     sem_post (&m_cmd_lock);
2979                     execute_omx_flush(OMX_ALL);
2980                 }
2981                 bFlag = 0;
2982             }
2983             /* Requesting transition from Executing to Paused */
2984             else if (eState == OMX_StatePause) {
2985                 DEBUG_PRINT_LOW("PAUSE Command Issued");
2986                 m_state = OMX_StatePause;
2987                 bFlag = 1;
2988             }
2989             /* Requesting transition from Executing to Loaded */
2990             else if (eState == OMX_StateLoaded) {
2991                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
2992                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2993                         OMX_COMPONENT_GENERATE_EVENT);
2994                 eRet = OMX_ErrorIncorrectStateTransition;
2995             }
2996             /* Requesting transition from Executing to WaitForResources */
2997             else if (eState == OMX_StateWaitForResources) {
2998                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
2999                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3000                         OMX_COMPONENT_GENERATE_EVENT);
3001                 eRet = OMX_ErrorIncorrectStateTransition;
3002             }
3003             /* Requesting transition from Executing to Executing */
3004             else if (eState == OMX_StateExecuting) {
3005                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
3006                 post_event(OMX_EventError,OMX_ErrorSameState,\
3007                         OMX_COMPONENT_GENERATE_EVENT);
3008                 eRet = OMX_ErrorSameState;
3009             }
3010             /* Requesting transition from Executing to Invalid */
3011             else if (eState == OMX_StateInvalid) {
3012                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
3013                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3014                 eRet = OMX_ErrorInvalidState;
3015             } else {
3016                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
3017                 eRet = OMX_ErrorBadParameter;
3018             }
3019         }
3020         /***************************/
3021         /* Current State is Pause  */
3022         /***************************/
3023         else if (m_state == OMX_StatePause) {
3024             /* Requesting transition from Pause to Executing */
3025             if (eState == OMX_StateExecuting) {
3026                 DEBUG_PRINT_LOW("Pause --> Executing");
3027                 m_state = OMX_StateExecuting;
3028                 bFlag = 1;
3029             }
3030             /* Requesting transition from Pause to Idle */
3031             else if (eState == OMX_StateIdle) {
3032                 /* Since error is None , we will post an event
3033                    at the end of this function definition */
3034                 DEBUG_PRINT_LOW("Pause --> Idle");
3035                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
3036                 if (!sem_posted) {
3037                     sem_posted = 1;
3038                     sem_post (&m_cmd_lock);
3039                     execute_omx_flush(OMX_ALL);
3040                 }
3041                 bFlag = 0;
3042             }
3043             /* Requesting transition from Pause to loaded */
3044             else if (eState == OMX_StateLoaded) {
3045                 DEBUG_PRINT_ERROR("Pause --> loaded");
3046                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3047                         OMX_COMPONENT_GENERATE_EVENT);
3048                 eRet = OMX_ErrorIncorrectStateTransition;
3049             }
3050             /* Requesting transition from Pause to WaitForResources */
3051             else if (eState == OMX_StateWaitForResources) {
3052                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
3053                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3054                         OMX_COMPONENT_GENERATE_EVENT);
3055                 eRet = OMX_ErrorIncorrectStateTransition;
3056             }
3057             /* Requesting transition from Pause to Pause */
3058             else if (eState == OMX_StatePause) {
3059                 DEBUG_PRINT_ERROR("Pause --> Pause");
3060                 post_event(OMX_EventError,OMX_ErrorSameState,\
3061                         OMX_COMPONENT_GENERATE_EVENT);
3062                 eRet = OMX_ErrorSameState;
3063             }
3064             /* Requesting transition from Pause to Invalid */
3065             else if (eState == OMX_StateInvalid) {
3066                 DEBUG_PRINT_ERROR("Pause --> Invalid");
3067                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3068                 eRet = OMX_ErrorInvalidState;
3069             } else {
3070                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
3071                 eRet = OMX_ErrorBadParameter;
3072             }
3073         }
3074         /***************************/
3075         /* Current State is WaitForResources  */
3076         /***************************/
3077         else if (m_state == OMX_StateWaitForResources) {
3078             /* Requesting transition from WaitForResources to Loaded */
3079             if (eState == OMX_StateLoaded) {
3080                 /* Since error is None , we will post an event
3081                    at the end of this function definition */
3082                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
3083             }
3084             /* Requesting transition from WaitForResources to WaitForResources */
3085             else if (eState == OMX_StateWaitForResources) {
3086                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
3087                 post_event(OMX_EventError,OMX_ErrorSameState,
3088                         OMX_COMPONENT_GENERATE_EVENT);
3089                 eRet = OMX_ErrorSameState;
3090             }
3091             /* Requesting transition from WaitForResources to Executing */
3092             else if (eState == OMX_StateExecuting) {
3093                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
3094                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3095                         OMX_COMPONENT_GENERATE_EVENT);
3096                 eRet = OMX_ErrorIncorrectStateTransition;
3097             }
3098             /* Requesting transition from WaitForResources to Pause */
3099             else if (eState == OMX_StatePause) {
3100                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
3101                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3102                         OMX_COMPONENT_GENERATE_EVENT);
3103                 eRet = OMX_ErrorIncorrectStateTransition;
3104             }
3105             /* Requesting transition from WaitForResources to Invalid */
3106             else if (eState == OMX_StateInvalid) {
3107                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
3108                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3109                 eRet = OMX_ErrorInvalidState;
3110             }
3111             /* Requesting transition from WaitForResources to Loaded -
3112                is NOT tested by Khronos TS */
3113 
3114         } else {
3115             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
3116             eRet = OMX_ErrorBadParameter;
3117         }
3118     }
3119     /********************************/
3120     /* Current State is Invalid */
3121     /*******************************/
3122     else if (m_state == OMX_StateInvalid) {
3123         /* State Transition from Inavlid to any state */
3124         if ((eState ==  OMX_StateLoaded) ||
3125             (eState == OMX_StateWaitForResources) ||
3126             (eState == OMX_StateIdle) ||
3127             (eState == OMX_StateExecuting) ||
3128             (eState == OMX_StatePause) ||
3129             (eState == OMX_StateInvalid)
3130         ) {
3131             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
3132             post_event(OMX_EventError,OMX_ErrorInvalidState,\
3133                     OMX_COMPONENT_GENERATE_EVENT);
3134             eRet = OMX_ErrorInvalidState;
3135         }
3136     } else if (cmd == OMX_CommandFlush) {
3137         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
3138                 "with param1: %u", (unsigned int)param1);
3139         send_codec_config();
3140         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
3141                     param1 == OMX_ALL)) {
3142             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
3143                struct timespec ts;
3144 
3145                clock_gettime(CLOCK_REALTIME, &ts);
3146                ts.tv_sec += 1;
3147                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
3148                        m_queued_codec_config_count);
3149                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
3150                if (sem_timedwait(&m_safe_flush, &ts)) {
3151                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
3152                }
3153                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
3154             }
3155         }
3156 
3157         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3158             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
3159         }
3160         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3161             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3162         }
3163         if (!sem_posted) {
3164             sem_posted = 1;
3165             DEBUG_PRINT_LOW("Set the Semaphore");
3166             sem_post (&m_cmd_lock);
3167             execute_omx_flush(param1);
3168         }
3169         bFlag = 0;
3170     } else if ( cmd == OMX_CommandPortEnable) {
3171         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
3172                 "with param1: %u", (unsigned int)param1);
3173         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3174             m_inp_bEnabled = OMX_TRUE;
3175 
3176             if ( (m_state == OMX_StateLoaded &&
3177                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3178                     || allocate_input_done()) {
3179                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
3180                         OMX_COMPONENT_GENERATE_EVENT);
3181             } else {
3182                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3183                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
3184                 // Skip the event notification
3185                 bFlag = 0;
3186             }
3187         }
3188         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3189             DEBUG_PRINT_LOW("Enable output Port command recieved");
3190             m_out_bEnabled = OMX_TRUE;
3191 
3192             if ( (m_state == OMX_StateLoaded &&
3193                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3194                     || (allocate_output_done())) {
3195                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
3196                         OMX_COMPONENT_GENERATE_EVENT);
3197 
3198             } else {
3199                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3200                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3201                 // Skip the event notification
3202                 bFlag = 0;
3203                 /* enable/disable downscaling if required */
3204                 ret = decide_downscalar();
3205                 if (ret) {
3206                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
3207                 }
3208             }
3209         }
3210     } else if (cmd == OMX_CommandPortDisable) {
3211         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
3212                 "with param1: %u", (unsigned int)param1);
3213         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3214             codec_config_flag = false;
3215             m_inp_bEnabled = OMX_FALSE;
3216             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3217                     && release_input_done()) {
3218                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
3219                         OMX_COMPONENT_GENERATE_EVENT);
3220             } else {
3221                 DEBUG_PRINT_HIGH("Set input port disable pending");
3222                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
3223                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3224                     if (!sem_posted) {
3225                         sem_posted = 1;
3226                         sem_post (&m_cmd_lock);
3227                     }
3228                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
3229                 }
3230 
3231                 // Skip the event notification
3232                 bFlag = 0;
3233             }
3234         }
3235         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3236             m_out_bEnabled = OMX_FALSE;
3237             DEBUG_PRINT_LOW("Disable output Port command recieved");
3238             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3239                     && release_output_done()) {
3240                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
3241                         OMX_COMPONENT_GENERATE_EVENT);
3242             } else {
3243                 DEBUG_PRINT_HIGH("Set output port disable pending");
3244                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3245                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3246                     if (!sem_posted) {
3247                         sem_posted = 1;
3248                         sem_post (&m_cmd_lock);
3249                     }
3250                     DEBUG_PRINT_HIGH("Set output port flush in disable pending");
3251                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
3252                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
3253                 }
3254                 // Skip the event notification
3255                 bFlag = 0;
3256 
3257             }
3258         }
3259     } else {
3260         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
3261         eRet = OMX_ErrorNotImplemented;
3262     }
3263     if (eRet == OMX_ErrorNone && bFlag) {
3264         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
3265     }
3266     if (!sem_posted) {
3267         sem_post(&m_cmd_lock);
3268     }
3269 
3270     return eRet;
3271 }
3272 
3273 /* ======================================================================
3274    FUNCTION
3275    omx_vdec::ExecuteOmxFlush
3276 
3277    DESCRIPTION
3278    Executes the OMX flush.
3279 
3280    PARAMETERS
3281    flushtype - input flush(1)/output flush(0)/ both.
3282 
3283    RETURN VALUE
3284    true/false
3285 
3286    ========================================================================== */
execute_omx_flush(OMX_U32 flushType)3287 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
3288 {
3289     bool bRet = false;
3290     struct v4l2_plane plane;
3291     struct v4l2_buffer v4l2_buf;
3292     struct v4l2_decoder_cmd dec;
3293     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
3294     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
3295     dec.cmd = V4L2_QCOM_CMD_FLUSH;
3296 
3297     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
3298 
3299     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
3300         output_flush_progress = true;
3301         dec.flags = V4L2_QCOM_CMD_FLUSH_CAPTURE;
3302     } else {
3303         /* XXX: The driver/hardware does not support flushing of individual ports
3304          * in all states. So we pretty much need to flush both ports internally,
3305          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
3306          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
3307          * we automatically omit sending the FLUSH done for the "opposite" port. */
3308         input_flush_progress = true;
3309         output_flush_progress = true;
3310         dec.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3311     }
3312 
3313     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
3314         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
3315         bRet = false;
3316     }
3317 
3318     return bRet;
3319 }
3320 /*=========================================================================
3321 FUNCTION : execute_output_flush
3322 
3323 DESCRIPTION
3324 Executes the OMX flush at OUTPUT PORT.
3325 
3326 PARAMETERS
3327 None.
3328 
3329 RETURN VALUE
3330 true/false
3331 ==========================================================================*/
execute_output_flush()3332 bool omx_vdec::execute_output_flush()
3333 {
3334     unsigned long p1 = 0; // Parameter - 1
3335     unsigned long p2 = 0; // Parameter - 2
3336     unsigned long ident = 0;
3337     bool bRet = true;
3338 
3339     /*Generate FBD for all Buffers in the FTBq*/
3340     pthread_mutex_lock(&m_lock);
3341     DEBUG_PRINT_LOW("Initiate Output Flush");
3342 
3343     //reset last render TS
3344     if(m_last_rendered_TS > 0) {
3345         m_last_rendered_TS = 0;
3346     }
3347 
3348     while (m_ftb_q.m_size) {
3349         m_ftb_q.pop_entry(&p1,&p2,&ident);
3350         if (ident == m_fill_output_msg ) {
3351             print_omx_buffer("Flush FBD", (OMX_BUFFERHEADERTYPE *)p2);
3352             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
3353         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
3354             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
3355         }
3356     }
3357     pthread_mutex_unlock(&m_lock);
3358     output_flush_progress = false;
3359 
3360     if (arbitrary_bytes) {
3361         prev_ts = LLONG_MAX;
3362         rst_prev_ts = true;
3363     }
3364     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
3365     return bRet;
3366 }
3367 /*=========================================================================
3368 FUNCTION : execute_input_flush
3369 
3370 DESCRIPTION
3371 Executes the OMX flush at INPUT PORT.
3372 
3373 PARAMETERS
3374 None.
3375 
3376 RETURN VALUE
3377 true/false
3378 ==========================================================================*/
execute_input_flush()3379 bool omx_vdec::execute_input_flush()
3380 {
3381     unsigned       i =0;
3382     unsigned long p1 = 0; // Parameter - 1
3383     unsigned long p2 = 0; // Parameter - 2
3384     unsigned long ident = 0;
3385     bool bRet = true;
3386 
3387     /*Generate EBD for all Buffers in the ETBq*/
3388     DEBUG_PRINT_LOW("Initiate Input Flush");
3389 
3390     pthread_mutex_lock(&m_lock);
3391     DEBUG_PRINT_LOW("Check if the Queue is empty");
3392     while (m_etb_q.m_size) {
3393         m_etb_q.pop_entry(&p1,&p2,&ident);
3394 
3395         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
3396             print_omx_buffer("Flush ETB_ARBITRARY", (OMX_BUFFERHEADERTYPE *)p2);
3397             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
3398         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
3399             pending_input_buffers++;
3400             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
3401             print_omx_buffer("Flush ETB", (OMX_BUFFERHEADERTYPE *)p2);
3402             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
3403         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
3404             print_omx_buffer("Flush EBD", (OMX_BUFFERHEADERTYPE *)p1);
3405             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
3406         }
3407     }
3408     time_stamp_dts.flush_timestamp();
3409     /*Check if Heap Buffers are to be flushed*/
3410     if (arbitrary_bytes && !(codec_config_flag)) {
3411         DEBUG_PRINT_LOW("Reset all the variables before flusing");
3412         h264_scratch.nFilledLen = 0;
3413         nal_count = 0;
3414         look_ahead_nal = false;
3415         frame_count = 0;
3416         h264_last_au_ts = LLONG_MAX;
3417         h264_last_au_flags = 0;
3418         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
3419         m_demux_entries = 0;
3420         DEBUG_PRINT_LOW("Initialize parser");
3421         if (m_frame_parser.mutils) {
3422             m_frame_parser.mutils->initialize_frame_checking_environment();
3423         }
3424 
3425         while (m_input_pending_q.m_size) {
3426             m_input_pending_q.pop_entry(&p1,&p2,&ident);
3427             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
3428         }
3429 
3430         if (psource_frame) {
3431             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
3432             psource_frame = NULL;
3433         }
3434 
3435         if (pdest_frame) {
3436             pdest_frame->nFilledLen = 0;
3437             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
3438                     (unsigned int)NULL);
3439             pdest_frame = NULL;
3440         }
3441         m_frame_parser.flush();
3442     } else if (codec_config_flag) {
3443         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
3444                 "is not sent to the driver yet");
3445     }
3446     pthread_mutex_unlock(&m_lock);
3447     input_flush_progress = false;
3448     if (!arbitrary_bytes) {
3449         prev_ts = LLONG_MAX;
3450         rst_prev_ts = true;
3451     }
3452 
3453     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
3454     return bRet;
3455 }
3456 
3457 /*=========================================================================
3458 FUNCTION : notify_flush_done
3459 
3460 DESCRIPTION
3461 Notifies flush done to the OMX Client.
3462 
3463 PARAMETERS
3464 ctxt -- Context information related to the self..
3465 
3466 RETURN VALUE
3467 NONE
3468 ==========================================================================*/
notify_flush_done(void * ctxt)3469 void omx_vdec::notify_flush_done(void *ctxt) {
3470 
3471     omx_vdec *pThis = (omx_vdec *) ctxt;
3472 
3473     if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
3474         if (BITMASK_PRESENT(&pThis->m_flags,
3475                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
3476             DEBUG_PRINT_LOW("Notify Output Flush done");
3477             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3478             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3479                 OMX_EventCmdComplete,OMX_CommandFlush,
3480                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
3481         }
3482 
3483         if (BITMASK_PRESENT(&pThis->m_flags,
3484                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
3485             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
3486             DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
3487             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3488                     OMX_EventCmdComplete,OMX_CommandFlush,
3489                     OMX_CORE_INPUT_PORT_INDEX,NULL );
3490             //clear hdr10plusinfo list upon input flush done
3491             clear_hdr10plusinfo();
3492         }
3493     }
3494 }
3495 
3496 /* ======================================================================
3497    FUNCTION
3498    omx_vdec::SendCommandEvent
3499 
3500    DESCRIPTION
3501    Send the event to decoder pipe.  This is needed to generate the callbacks
3502    in decoder thread context.
3503 
3504    PARAMETERS
3505    None.
3506 
3507    RETURN VALUE
3508    true/false
3509 
3510    ========================================================================== */
post_event(unsigned long p1,unsigned long p2,unsigned long id)3511 bool omx_vdec::post_event(unsigned long p1,
3512         unsigned long p2,
3513         unsigned long id)
3514 {
3515     bool bRet = false;
3516 
3517     /* Just drop messages typically generated by hardware (w/o client request),
3518      * if we've reported an error to client. */
3519     if (m_error_propogated) {
3520         switch (id) {
3521             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
3522             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
3523                 DEBUG_PRINT_ERROR("Dropping message %lx "
3524                         "since client expected to be in error state", id);
3525                 return false;
3526             default:
3527                 /* whatever */
3528                 break;
3529         }
3530     }
3531 
3532     pthread_mutex_lock(&m_lock);
3533 
3534     if (id == m_fill_output_msg ||
3535             id == OMX_COMPONENT_GENERATE_FBD ||
3536             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
3537             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
3538         m_ftb_q.insert_entry(p1,p2,id);
3539     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
3540             id == OMX_COMPONENT_GENERATE_EBD ||
3541             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
3542             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
3543         m_etb_q.insert_entry(p1,p2,id);
3544     } else {
3545         DEBUG_PRINT_HIGH("post_event(%ld, %ld, %ld)", p1, p2, id);
3546         m_cmd_q.insert_entry(p1,p2,id);
3547     }
3548 
3549     bRet = true;
3550     post_message(this, id);
3551 
3552     pthread_mutex_unlock(&m_lock);
3553 
3554     return bRet;
3555 }
3556 
vdec_query_cap(struct v4l2_queryctrl & cap)3557 bool inline omx_vdec::vdec_query_cap(struct v4l2_queryctrl &cap) {
3558 
3559     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &cap)) {
3560         DEBUG_PRINT_ERROR("Query caps for id = %u failed\n", cap.id);
3561         return false;
3562     }
3563     return true;
3564 }
3565 
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)3566 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
3567 {
3568     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3569     struct v4l2_queryctrl profile_cap, level_cap;
3570     int v4l2_profile;
3571     int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
3572                             QOMX_VIDEO_AVCProfileBaseline,
3573                             QOMX_VIDEO_AVCProfileMain,
3574                             QOMX_VIDEO_AVCProfileConstrainedHigh,
3575                             QOMX_VIDEO_AVCProfileHigh };
3576     int hevc_profiles[3] = { OMX_VIDEO_HEVCProfileMain,
3577                              OMX_VIDEO_HEVCProfileMain10,
3578                              OMX_VIDEO_HEVCProfileMain10HDR10 };
3579     int mpeg2_profiles[2] = { OMX_VIDEO_MPEG2ProfileSimple,
3580                               OMX_VIDEO_MPEG2ProfileMain};
3581     int vp9_profiles[4] = { OMX_VIDEO_VP9Profile0,
3582                             OMX_VIDEO_VP9Profile2,
3583                             OMX_VIDEO_VP9Profile2HDR,
3584                             OMX_VIDEO_VP9Profile2HDR10Plus};
3585 
3586     if (!profileLevelType)
3587         return OMX_ErrorBadParameter;
3588 
3589     memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
3590     memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
3591 
3592     if (output_capability == V4L2_PIX_FMT_H264) {
3593         level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3594         profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3595     } else if (output_capability == V4L2_PIX_FMT_VP8) {
3596         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3597     } else if (output_capability == V4L2_PIX_FMT_VP9) {
3598         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL;
3599         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE;
3600     } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3601         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
3602         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
3603     } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3604         level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL;
3605         profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE;
3606     } else {
3607         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
3608         return OMX_ErrorInvalidComponent;
3609     }
3610 
3611     if (profile_cap.id) {
3612         if(!vdec_query_cap(profile_cap)) {
3613             DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
3614             return OMX_ErrorHardware;
3615         }
3616     }
3617 
3618     if (level_cap.id) {
3619         if(!vdec_query_cap(level_cap)) {
3620             DEBUG_PRINT_ERROR("Getting capabilities for level failed");
3621             return OMX_ErrorHardware;
3622         }
3623     }
3624 
3625     /* Get the corresponding omx level from v4l2 level */
3626     if (!profile_level_converter::convert_v4l2_level_to_omx(output_capability, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
3627         DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
3628         return OMX_ErrorHardware;
3629     }
3630 
3631     /* For given profile index get corresponding profile that needs to be supported */
3632     if (profileLevelType->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
3633         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
3634         return OMX_ErrorBadPortIndex;
3635     }
3636 
3637     if (output_capability == V4L2_PIX_FMT_H264) {
3638         if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
3639             profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
3640         } else {
3641             DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3642                                           (unsigned int)profileLevelType->nProfileIndex);
3643             return OMX_ErrorNoMore;
3644         }
3645     } else if (output_capability == V4L2_PIX_FMT_VP8) {
3646         if (profileLevelType->nProfileIndex == 0) {
3647             profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
3648         } else {
3649             DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3650                                           (unsigned int)profileLevelType->nProfileIndex);
3651             return OMX_ErrorNoMore;
3652         }
3653         /* Driver has no notion of VP8 profile. Only one profile is supported.  Return this */
3654         return OMX_ErrorNone;
3655     } else if (output_capability == V4L2_PIX_FMT_VP9) {
3656         if (profileLevelType->nProfileIndex < (sizeof(vp9_profiles)/sizeof(int))) {
3657             profileLevelType->eProfile = vp9_profiles[profileLevelType->nProfileIndex];
3658         } else {
3659             DEBUG_PRINT_LOW("VP9: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3660                                           (unsigned int)profileLevelType->nProfileIndex);
3661             return OMX_ErrorNoMore;
3662         }
3663     } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3664         if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
3665             profileLevelType->eProfile =  hevc_profiles[profileLevelType->nProfileIndex];
3666         } else {
3667             DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3668                                          (unsigned int)profileLevelType->nProfileIndex);
3669             return OMX_ErrorNoMore;
3670         }
3671     } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3672         if (profileLevelType->nProfileIndex < (sizeof(mpeg2_profiles)/sizeof(int))) {
3673             profileLevelType->eProfile = mpeg2_profiles[profileLevelType->nProfileIndex];
3674         } else {
3675             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3676                                          (unsigned int)profileLevelType->nProfileIndex);
3677             return OMX_ErrorNoMore;
3678         }
3679     }
3680 
3681     /* Check if the profile is supported by driver or not  */
3682     /* During query caps of profile driver sends a mask of */
3683     /* of all v4l2 profiles supported(in the flags field)  */
3684     if((output_capability != V4L2_PIX_FMT_HEVC) &&
3685          (output_capability != V4L2_PIX_FMT_VP9)) {
3686         if (!profile_level_converter::convert_omx_profile_to_v4l2(output_capability, profileLevelType->eProfile, &v4l2_profile)) {
3687             DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3688             return OMX_ErrorHardware;
3689         }
3690     }else if(output_capability == V4L2_PIX_FMT_HEVC) { //convert omx profile to v4l2 profile for HEVC Main10 and Main10HDR10 profiles,seperately
3691         switch (profileLevelType->eProfile) {
3692             case OMX_VIDEO_HEVCProfileMain:
3693                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
3694                 break;
3695             case OMX_VIDEO_HEVCProfileMain10:
3696             case OMX_VIDEO_HEVCProfileMain10HDR10:
3697                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
3698                 break;
3699             default:
3700                 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3701                 return OMX_ErrorHardware;
3702         }
3703     }else { //convert omx profile to v4l2 profile for VP9 Profile2 and VP9 Profile2HDR profiles,seperately
3704         switch (profileLevelType->eProfile) {
3705             case OMX_VIDEO_VP9Profile0:
3706                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0;
3707                 break;
3708             case OMX_VIDEO_VP9Profile2:
3709             case OMX_VIDEO_VP9Profile2HDR:
3710                 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10;
3711                 break;
3712             default:
3713                 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3714                 return OMX_ErrorHardware;
3715         }
3716     }
3717     if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
3718         DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
3719         eRet = OMX_ErrorNoMore;
3720     }
3721 
3722     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
3723             (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
3724     return eRet;
3725 }
3726 
3727 /* ======================================================================
3728    FUNCTION
3729    omx_vdec::GetParameter
3730 
3731    DESCRIPTION
3732    OMX Get Parameter method implementation
3733 
3734    PARAMETERS
3735    <TBD>.
3736 
3737    RETURN VALUE
3738    Error None if successful.
3739 
3740    ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)3741 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
3742         OMX_IN OMX_INDEXTYPE paramIndex,
3743         OMX_INOUT OMX_PTR     paramData)
3744 {
3745     (void) hComp;
3746     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3747 
3748     DEBUG_PRINT_LOW("get_parameter:");
3749     if (m_state == OMX_StateInvalid) {
3750         DEBUG_PRINT_ERROR("Get Param in Invalid State");
3751         return OMX_ErrorInvalidState;
3752     }
3753     if (paramData == NULL) {
3754         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
3755         return OMX_ErrorBadParameter;
3756     }
3757     switch ((unsigned long)paramIndex) {
3758         case OMX_IndexParamPortDefinition: {
3759                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
3760                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
3761                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3762                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
3763 
3764                                OMX_COLOR_FORMATTYPE drv_color_format;
3765                                bool status = false;
3766 
3767                                if (!client_buffers.is_color_conversion_enabled()) {
3768                                    status = client_buffers.get_color_format(drv_color_format);
3769                                }
3770 
3771                                if (decide_dpb_buffer_mode()) {
3772                                    DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
3773                                    return OMX_ErrorBadParameter;
3774                                }
3775 
3776                               if (status) {
3777                                  if (!client_buffers.is_color_conversion_enabled()) {
3778                                          client_buffers.set_client_buffers_disabled(true);
3779                                          client_buffers.set_color_format(drv_color_format);
3780                                  }
3781                               }
3782 
3783                                eRet = update_portdef(portDefn);
3784                                if (eRet == OMX_ErrorNone)
3785                                    m_port_def = *portDefn;
3786                                break;
3787                            }
3788         case OMX_IndexParamVideoInit: {
3789                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3790                               OMX_PORT_PARAM_TYPE *portParamType =
3791                                   (OMX_PORT_PARAM_TYPE *) paramData;
3792                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
3793 
3794                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3795                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3796                               portParamType->nPorts           = 2;
3797                               portParamType->nStartPortNumber = 0;
3798                               break;
3799                           }
3800         case OMX_IndexParamVideoPortFormat: {
3801                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3802                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3803                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3804                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
3805 
3806                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
3807                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
3808 
3809                                 if (0 == portFmt->nPortIndex) {
3810                                     if (0 == portFmt->nIndex) {
3811                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
3812                                         portFmt->eCompressionFormat = eCompressionFormat;
3813                                     } else {
3814                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
3815                                                 " NoMore compression formats");
3816                                         eRet =  OMX_ErrorNoMore;
3817                                     }
3818                                 } else if (1 == portFmt->nPortIndex) {
3819                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
3820 
3821                                     // Distinguish non-surface mode from normal playback use-case based on
3822                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
3823                                     // For non-android, use the default list
3824                                     // Also use default format-list if FLEXIBLE YUV is supported,
3825                                     // as the client negotiates the standard color-format if it needs to
3826                                     bool useNonSurfaceMode = false;
3827 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) && !defined(USE_GBM)
3828                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
3829 #endif
3830                                     portFmt->eColorFormat = useNonSurfaceMode ?
3831                                         getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
3832                                         getPreferredColorFormatDefaultMode(portFmt->nIndex);
3833 
3834                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
3835                                         eRet = OMX_ErrorNoMore;
3836                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
3837                                                 " NoMore Color formats");
3838                                     }
3839                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
3840                                 } else {
3841                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
3842                                             (int)portFmt->nPortIndex);
3843                                     eRet = OMX_ErrorBadPortIndex;
3844                                 }
3845                                 break;
3846                             }
3847                             /*Component should support this port definition*/
3848         case OMX_IndexParamAudioInit: {
3849                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3850                               OMX_PORT_PARAM_TYPE *audioPortParamType =
3851                                   (OMX_PORT_PARAM_TYPE *) paramData;
3852                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
3853                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3854                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3855                               audioPortParamType->nPorts           = 0;
3856                               audioPortParamType->nStartPortNumber = 0;
3857                               break;
3858                           }
3859                           /*Component should support this port definition*/
3860         case OMX_IndexParamImageInit: {
3861                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3862                               OMX_PORT_PARAM_TYPE *imagePortParamType =
3863                                   (OMX_PORT_PARAM_TYPE *) paramData;
3864                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
3865                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3866                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3867                               imagePortParamType->nPorts           = 0;
3868                               imagePortParamType->nStartPortNumber = 0;
3869                               break;
3870 
3871                           }
3872                           /*Component should support this port definition*/
3873         case OMX_IndexParamOtherInit: {
3874                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
3875                                       paramIndex);
3876                               eRet =OMX_ErrorUnsupportedIndex;
3877                               break;
3878                           }
3879         case OMX_IndexParamStandardComponentRole: {
3880                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
3881                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
3882                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3883                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
3884                                   comp_role->nSize = sizeof(*comp_role);
3885 
3886                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
3887                                           paramIndex);
3888                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
3889                                           OMX_MAX_STRINGNAME_SIZE);
3890                                   break;
3891                               }
3892                               /* Added for parameter test */
3893         case OMX_IndexParamPriorityMgmt: {
3894                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
3895                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
3896                                  (OMX_PRIORITYMGMTTYPE *) paramData;
3897                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
3898                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
3899                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
3900 
3901                              break;
3902                          }
3903                          /* Added for parameter test */
3904         case OMX_IndexParamCompBufferSupplier: {
3905                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
3906                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
3907                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3908                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
3909 
3910                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
3911                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
3912                                    if (0 == bufferSupplierType->nPortIndex)
3913                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3914                                    else if (1 == bufferSupplierType->nPortIndex)
3915                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3916                                    else
3917                                        eRet = OMX_ErrorBadPortIndex;
3918 
3919 
3920                                    break;
3921                                }
3922         case OMX_IndexParamVideoAvc: {
3923                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
3924                                      paramIndex);
3925                              break;
3926                          }
3927         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
3928                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
3929                                      paramIndex);
3930                              break;
3931                          }
3932         case OMX_IndexParamVideoMpeg2: {
3933                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
3934                                        paramIndex);
3935                                break;
3936                            }
3937         case OMX_IndexParamVideoProfileLevelQuerySupported: {
3938                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3939                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
3940                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3941                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3942                                         eRet = get_supported_profile_level(profileLevelType);
3943                                         break;
3944                                     }
3945 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3946         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
3947                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
3948                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
3949                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3950                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3951 
3952                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
3953                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
3954                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
3955                                             } else {
3956                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
3957                                             }
3958                                         } else {
3959                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
3960                                             eRet = OMX_ErrorBadParameter;
3961                                         }
3962                                     }
3963                                     break;
3964 #endif
3965 
3966 #ifdef FLEXYUV_SUPPORTED
3967         case OMX_QcomIndexFlexibleYUVDescription: {
3968                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
3969                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
3970                 eRet = describeColorFormat(paramData);
3971                 if (eRet == OMX_ErrorUnsupportedSetting) {
3972                     DEBUG_PRINT_LOW("The standard OMX linear formats are understood by client. Please ignore this  Unsupported Setting (0x80001019).");
3973                 }
3974                 break;
3975             }
3976 #endif
3977         case OMX_IndexParamVideoProfileLevelCurrent: {
3978              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3979              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3980              struct v4l2_control profile_control, level_control;
3981 
3982              switch (drv_ctx.decoder_format) {
3983                  case VDEC_CODECTYPE_H264:
3984                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3985                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3986                      break;
3987                  default:
3988                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
3989                      eRet = OMX_ErrorNotImplemented;
3990                      break;
3991              }
3992 
3993              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
3994                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
3995                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
3996                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
3997                         break;
3998                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
3999                         pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
4000                         break;
4001                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
4002                         pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
4003                         break;
4004                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
4005                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
4006                         break;
4007                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
4008                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
4009                         break;
4010                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
4011                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
4012                         break;
4013                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
4014                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
4015                         break;
4016                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
4017                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
4018                         break;
4019                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
4020                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
4021                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
4022                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
4023                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
4024                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
4025                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
4026                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
4027                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
4028                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
4029                         eRet = OMX_ErrorUnsupportedIndex;
4030                         break;
4031                 }
4032              } else {
4033                  eRet = OMX_ErrorUnsupportedIndex;
4034              }
4035 
4036 
4037              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
4038                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
4039                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
4040                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
4041                         break;
4042                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
4043                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
4044                         break;
4045                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
4046                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
4047                         break;
4048                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
4049                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
4050                         break;
4051                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
4052                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
4053                         break;
4054                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4055                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
4056                         break;
4057                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4058                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
4059                         break;
4060                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4061                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
4062                         break;
4063                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4064                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
4065                         break;
4066                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4067                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
4068                         break;
4069                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4070                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
4071                         break;
4072                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4073                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
4074                         break;
4075                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4076                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
4077                         break;
4078                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4079                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
4080                         break;
4081                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4082                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
4083                         break;
4084                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4085                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
4086                         break;
4087                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4088                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
4089                         break;
4090                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_0:
4091                         pParam->eLevel = OMX_VIDEO_AVCLevel6;
4092                         break;
4093                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_1:
4094                         pParam->eLevel = OMX_VIDEO_AVCLevel61;
4095                         break;
4096                     case V4L2_MPEG_VIDEO_H264_LEVEL_6_2:
4097                         pParam->eLevel = OMX_VIDEO_AVCLevel62;
4098                         break;
4099                     default:
4100                         eRet = OMX_ErrorUnsupportedIndex;
4101                         break;
4102                 }
4103              } else {
4104                  eRet = OMX_ErrorUnsupportedIndex;
4105              }
4106 
4107              break;
4108 
4109          }
4110         case OMX_QTIIndexParamVideoClientExtradata:
4111         {
4112             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4113             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
4114             QOMX_EXTRADATA_ENABLE *pParam =
4115                 (QOMX_EXTRADATA_ENABLE *)paramData;
4116             if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4117                 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE;
4118                 eRet = OMX_ErrorNone;
4119             } else {
4120                 eRet = OMX_ErrorUnsupportedIndex;
4121             }
4122             break;
4123         }
4124         case OMX_QTIIndexParamDitherControl:
4125         {
4126             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
4127             DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL");
4128             QOMX_VIDEO_DITHER_CONTROL *pParam =
4129                 (QOMX_VIDEO_DITHER_CONTROL *) paramData;
4130             pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config;
4131             eRet = OMX_ErrorNone;
4132             break;
4133         }
4134         case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
4135         {
4136             VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
4137             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
4138             OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam =
4139                 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) paramData;
4140             pParam->eProfile = mClientSetProfile;
4141             pParam->eLevel = mClientSetLevel;
4142             eRet = OMX_ErrorNone;
4143             break;
4144         }
4145         default: {
4146                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
4147                  eRet =OMX_ErrorUnsupportedIndex;
4148              }
4149 
4150     }
4151 
4152     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
4153             drv_ctx.video_resolution.frame_width,
4154             drv_ctx.video_resolution.frame_height,
4155             drv_ctx.video_resolution.stride,
4156             drv_ctx.video_resolution.scan_lines);
4157 
4158     return eRet;
4159 }
4160 
4161 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_PTR data)4162 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
4163 {
4164     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
4165     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4166     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
4167 
4168     if ((params == NULL) ||
4169             (params->nativeBuffer == NULL) ||
4170             (params->nativeBuffer->handle == NULL) ||
4171             !m_enable_android_native_buffers)
4172         return OMX_ErrorBadParameter;
4173     m_use_android_native_buffers = OMX_TRUE;
4174     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4175     private_handle_t *handle = (private_handle_t *)nBuf->handle;
4176     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
4177         OMX_U8 *buffer = NULL;
4178         if (!secure_mode) {
4179             buffer = (OMX_U8*)mmap(0, handle->size,
4180                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4181             if (buffer == MAP_FAILED) {
4182                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4183                 return OMX_ErrorInsufficientResources;
4184             }
4185         }
4186         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
4187     } else {
4188         eRet = OMX_ErrorBadParameter;
4189     }
4190     return eRet;
4191 }
4192 #endif
4193 
enable_smoothstreaming()4194 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
4195     struct v4l2_control control;
4196     struct v4l2_format fmt;
4197     /*control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
4198     control.value = 1;
4199     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
4200     if (rc < 0) {
4201         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
4202         return OMX_ErrorHardware;
4203     }*/
4204     m_smoothstreaming_mode = true;
4205     return OMX_ErrorNone;
4206 }
4207 
4208 /* ======================================================================
4209    FUNCTION
4210    omx_vdec::Setparameter
4211 
4212    DESCRIPTION
4213    OMX Set Parameter method implementation.
4214 
4215    PARAMETERS
4216    <TBD>.
4217 
4218    RETURN VALUE
4219    OMX Error None if successful.
4220 
4221    ========================================================================== */
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)4222 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
4223         OMX_IN OMX_INDEXTYPE paramIndex,
4224         OMX_IN OMX_PTR        paramData)
4225 {
4226     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4227     int ret=0;
4228     struct v4l2_format fmt;
4229 #ifdef _ANDROID_
4230     char property_value[PROPERTY_VALUE_MAX] = {0};
4231 #endif
4232     if (m_state == OMX_StateInvalid) {
4233         DEBUG_PRINT_ERROR("Set Param in Invalid State");
4234         return OMX_ErrorInvalidState;
4235     }
4236     if (paramData == NULL) {
4237         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
4238         return OMX_ErrorBadParameter;
4239     }
4240     if ((m_state != OMX_StateLoaded) &&
4241             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
4242             (m_out_bEnabled == OMX_TRUE) &&
4243             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
4244             (m_inp_bEnabled == OMX_TRUE)) {
4245         DEBUG_PRINT_ERROR("Set Param in Invalid State");
4246         return OMX_ErrorIncorrectStateOperation;
4247     }
4248     switch ((unsigned long)paramIndex) {
4249         case OMX_IndexParamPortDefinition: {
4250                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
4251                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
4252                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
4253                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
4254                                //been called.
4255                                DEBUG_PRINT_LOW(
4256                                        "set_parameter: OMX_IndexParamPortDefinition: dir %d port %d wxh %dx%d count: min %d actual %d size %d",
4257                                        (int)portDefn->eDir, (int)portDefn->nPortIndex,
4258                                        (int)portDefn->format.video.nFrameWidth,
4259                                        (int)portDefn->format.video.nFrameHeight,
4260                                        (int)portDefn->nBufferCountMin,
4261                                        (int)portDefn->nBufferCountActual,
4262                                        (int)portDefn->nBufferSize);
4263 
4264                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4265                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
4266                                                           portDefn->nBufferCountActual);
4267                                    eRet = OMX_ErrorBadParameter;
4268                                    break;
4269                                }
4270                                if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
4271                                    if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
4272                                         portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
4273                                         DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
4274                                                           portDefn->nBufferCountActual, portDefn->nBufferSize);
4275                                         eRet = OMX_ErrorBadParameter;
4276                                         break;
4277                                    }
4278                                     m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
4279                                             portDefn->nBufferCountActual);
4280                                     break;
4281                                }
4282 
4283                                if (OMX_DirOutput == portDefn->eDir) {
4284                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
4285                                    bool port_format_changed = false;
4286                                    m_display_id = portDefn->format.video.pNativeWindow;
4287                                    unsigned int buffer_size;
4288                                    /* update output port resolution with client supplied dimensions
4289                                       in case scaling is enabled, else it follows input resolution set
4290                                    */
4291                                    if (decide_dpb_buffer_mode()) {
4292                                        DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
4293                                        return OMX_ErrorBadParameter;
4294                                    }
4295                                    if (is_down_scalar_enabled) {
4296                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
4297                                                (unsigned int)portDefn->format.video.nFrameWidth,
4298                                                (unsigned int)portDefn->format.video.nFrameHeight);
4299                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
4300                                                portDefn->format.video.nFrameWidth != 0x0) {
4301                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
4302                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4303                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
4304                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4305                                            if (ret) {
4306                                                DEBUG_PRINT_ERROR("Get Resolution failed");
4307                                                eRet = OMX_ErrorHardware;
4308                                                break;
4309                                            }
4310                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
4311                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
4312                                                    port_format_changed = true;
4313                                            }
4314 
4315                                            /* set crop info */
4316                                            rectangle.nLeft = 0;
4317                                            rectangle.nTop = 0;
4318                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
4319                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
4320 
4321                                            m_extradata_info.output_crop_rect.nLeft = 0;
4322                                            m_extradata_info.output_crop_rect.nTop = 0;
4323                                            m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth;
4324                                            m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight;
4325 
4326                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
4327                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4328                                            fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
4329                                            fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
4330                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
4331                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
4332                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
4333                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4334                                            if (ret) {
4335                                                DEBUG_PRINT_ERROR("Set Resolution failed");
4336                                                eRet = errno == EBUSY ? OMX_ErrorInsufficientResources : OMX_ErrorUnsupportedSetting;
4337                                            } else
4338                                                eRet = get_buffer_req(&drv_ctx.op_buf);
4339                                        }
4340 
4341                                        if (eRet) {
4342                                            break;
4343                                        }
4344                                    }
4345 
4346                                    if (eRet) {
4347                                        break;
4348                                    }
4349 
4350                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4351                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
4352                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4353                                        eRet = OMX_ErrorBadParameter;
4354                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
4355                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
4356                                        eRet = OMX_ErrorBadParameter;
4357                                    } else if (!port_format_changed) {
4358 
4359                                        // Buffer count can change only when port is unallocated
4360                                        if (m_out_mem_ptr &&
4361                                                 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
4362                                                 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
4363 
4364                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
4365                                            eRet = OMX_ErrorInvalidState;
4366                                            break;
4367                                        }
4368 
4369                                        // route updating of buffer requirements via c2d proxy.
4370                                        // Based on whether c2d is enabled, requirements will be handed
4371                                        // to the vidc driver appropriately
4372                                        eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
4373                                                 portDefn->nBufferCountActual);
4374                                        if (eRet == OMX_ErrorNone) {
4375                                            m_port_def = *portDefn;
4376                                        } else {
4377                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
4378                                                    drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
4379                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4380                                            eRet = OMX_ErrorBadParameter;
4381                                        }
4382                                    }
4383                                } else if (OMX_DirInput == portDefn->eDir) {
4384                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
4385                                    bool port_format_changed = false;
4386                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
4387                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
4388                                        // Frame rate only should be set if this is a "known value" or to
4389                                        // activate ts prediction logic (arbitrary mode only) sending input
4390                                        // timestamps with max value (LLONG_MAX).
4391                                        m_fps_received = portDefn->format.video.xFramerate;
4392                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
4393                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
4394                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
4395                                                drv_ctx.frame_rate.fps_denominator);
4396                                        if (!drv_ctx.frame_rate.fps_numerator) {
4397                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4398                                            drv_ctx.frame_rate.fps_numerator = 30;
4399                                        }
4400                                        if (drv_ctx.frame_rate.fps_denominator)
4401                                            drv_ctx.frame_rate.fps_numerator = (int)
4402                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4403                                        drv_ctx.frame_rate.fps_denominator = 1;
4404                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4405                                            drv_ctx.frame_rate.fps_numerator;
4406                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
4407                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
4408                                                (float)drv_ctx.frame_rate.fps_denominator);
4409 
4410                                        struct v4l2_outputparm oparm;
4411                                        /*XXX: we're providing timing info as seconds per frame rather than frames
4412                                         * per second.*/
4413                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4414                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4415 
4416                                        struct v4l2_streamparm sparm;
4417                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4418                                        sparm.parm.output = oparm;
4419                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4420                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
4421                                            eRet = OMX_ErrorHardware;
4422                                            break;
4423                                        }
4424                                    }
4425 
4426                                    if (drv_ctx.video_resolution.frame_height !=
4427                                            portDefn->format.video.nFrameHeight ||
4428                                            drv_ctx.video_resolution.frame_width  !=
4429                                            portDefn->format.video.nFrameWidth) {
4430                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
4431                                                (unsigned int)portDefn->format.video.nFrameWidth,
4432                                                (unsigned int)portDefn->format.video.nFrameHeight);
4433                                        port_format_changed = true;
4434                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
4435                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
4436                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
4437                                            if (m_smoothstreaming_mode &&
4438                                                    ((frameWidth * frameHeight) <
4439                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
4440                                                frameWidth = m_smoothstreaming_width;
4441                                                frameHeight = m_smoothstreaming_height;
4442                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
4443                                                        "for adaptive-playback/smooth-streaming",
4444                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
4445                                            }
4446 
4447                                            m_extradata_info.output_crop_rect.nLeft = 0;
4448                                            m_extradata_info.output_crop_rect.nTop = 0;
4449                                            m_extradata_info.output_crop_rect.nWidth = frameWidth;
4450                                            m_extradata_info.output_crop_rect.nHeight = frameHeight;
4451 
4452                                            update_resolution(frameWidth, frameHeight,
4453                                                    frameWidth, frameHeight);
4454                                            if (is_down_scalar_enabled) {
4455                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
4456                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4457                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4458                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4459                                                fmt.fmt.pix_mp.pixelformat = output_capability;
4460                                                DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d",
4461                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4462                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4463                                            } else {
4464                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
4465                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4466                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4467                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4468                                                fmt.fmt.pix_mp.pixelformat = output_capability;
4469                                                DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
4470                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4471                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4472                                                fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4473                                                fmt.fmt.pix_mp.pixelformat = capture_capability;
4474                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4475                                            }
4476                                            if (ret) {
4477                                                DEBUG_PRINT_ERROR("Set Resolution failed");
4478                                                eRet = errno == EBUSY ? OMX_ErrorInsufficientResources : OMX_ErrorUnsupportedSetting;
4479                                            } else {
4480                                                if (!is_down_scalar_enabled)
4481                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
4482                                            }
4483                                            if (eRet)
4484                                                break;
4485                                        }
4486                                    }
4487                                    if (m_custom_buffersize.input_buffersize
4488                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
4489                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
4490                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
4491                                        eRet = OMX_ErrorBadParameter;
4492                                        break;
4493                                    }
4494                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4495                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
4496                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4497                                        eRet = OMX_ErrorBadParameter;
4498                                        break;
4499                                    }
4500                                    // Buffer count can change only when port is unallocated
4501                                    if (m_inp_mem_ptr &&
4502                                             (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
4503                                             portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
4504                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
4505                                        eRet = OMX_ErrorInvalidState;
4506                                        break;
4507                                    }
4508 
4509                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
4510                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
4511                                        port_format_changed = true;
4512                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
4513                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
4514                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
4515                                            (~(buffer_prop->alignment - 1));
4516                                        eRet = set_buffer_req(buffer_prop);
4517                                    }
4518                                    if (false == port_format_changed) {
4519                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
4520                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
4521                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4522                                        eRet = OMX_ErrorBadParameter;
4523                                    }
4524                                } else if (portDefn->eDir ==  OMX_DirMax) {
4525                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
4526                                            (int)portDefn->nPortIndex);
4527                                    eRet = OMX_ErrorBadPortIndex;
4528                                }
4529                            }
4530                            break;
4531         case OMX_IndexParamVideoPortFormat: {
4532                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
4533                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
4534                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
4535                                 int ret=0;
4536                                 struct v4l2_format fmt;
4537                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
4538                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
4539 
4540                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4541                                 if (1 == portFmt->nPortIndex) {
4542                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4543                                     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4544                                     if (ret < 0) {
4545                                         DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
4546                                         return OMX_ErrorBadParameter;
4547                                     }
4548                                     enum vdec_output_format op_format;
4549                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4550                                                      QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
4551                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
4552                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
4553                                         //check if the required color format is a supported flexible format
4554                                         is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4555                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4556                                                    QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
4557                                                portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
4558                                         portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
4559                                         op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12_UBWC;
4560                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
4561                                         //check if the required color format is a supported flexible format
4562                                         is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4563                                     } else {
4564                                         eRet = OMX_ErrorBadParameter;
4565                                     }
4566 
4567                                     if (eRet == OMX_ErrorNone) {
4568                                         drv_ctx.output_format = op_format;
4569                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4570                                         if (ret) {
4571                                             DEBUG_PRINT_ERROR("Set output format failed");
4572                                             eRet = OMX_ErrorUnsupportedSetting;
4573                                             /*TODO: How to handle this case */
4574                                         } else {
4575                                             eRet = get_buffer_req(&drv_ctx.op_buf);
4576                                         }
4577                                     }
4578                                     if (eRet == OMX_ErrorNone) {
4579                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
4580                                             DEBUG_PRINT_ERROR("Set color format failed");
4581                                             eRet = OMX_ErrorBadParameter;
4582                                         }
4583                                     }
4584                                 }
4585                             }
4586                             break;
4587         case OMX_QcomIndexPortDefn: {
4588                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
4589                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
4590                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
4591                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
4592                                     (unsigned int)portFmt->nFramePackingFormat);
4593 
4594                             /* Input port */
4595                             if (portFmt->nPortIndex == 0) {
4596                                 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
4597                                 //   - headers are allocated and
4598                                 //   - headers-indices are derived
4599                                 // Avoid changing arbitrary_bytes when the port is already allocated
4600                                 if (m_inp_mem_ptr) {
4601                                     DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
4602                                     return OMX_ErrorUnsupportedSetting;
4603                                 }
4604                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
4605                                     if (secure_mode || m_input_pass_buffer_fd) {
4606                                         arbitrary_bytes = false;
4607                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
4608                                         eRet = OMX_ErrorUnsupportedSetting;
4609                                     } else {
4610                                         arbitrary_bytes = true;
4611                                     }
4612                                 } else if (portFmt->nFramePackingFormat ==
4613                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
4614                                     arbitrary_bytes = false;
4615                                 } else {
4616                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
4617                                             (unsigned int)portFmt->nFramePackingFormat);
4618                                     eRet = OMX_ErrorUnsupportedSetting;
4619                                 }
4620                                 //Explicitly disable arb mode for unsupported codecs
4621                                 bool is_arb_supported = false;
4622                                 if (arbitrary_bytes) {
4623                                    switch (drv_ctx.decoder_format) {
4624                                    case VDEC_CODECTYPE_H264:
4625                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_H264;
4626                                       break;
4627                                    case VDEC_CODECTYPE_HEVC:
4628                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_HEVC;
4629                                       break;
4630                                    case VDEC_CODECTYPE_MPEG2:
4631                                       is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_MPEG2;
4632                                       break;
4633                                    default:
4634                                       DEBUG_PRINT_HIGH("Arbitrary bytes mode not enabled for this Codec");
4635                                       break;
4636                                    }
4637 
4638                                    if (!is_arb_supported) {
4639                                        DEBUG_PRINT_ERROR("Setparameter: Disabling arbitrary bytes mode explicitly");
4640                                        arbitrary_bytes = false;
4641                                        eRet = OMX_ErrorUnsupportedSetting;
4642                                    }
4643                                 }
4644                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
4645                                 DEBUG_PRINT_ERROR("Unsupported at O/P port");
4646                                 eRet = OMX_ErrorUnsupportedSetting;
4647                             }
4648                             break;
4649                         }
4650         case OMX_QTIIndexParamVideoClientExtradata: {
4651                                   VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4652                                   DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
4653                                   QOMX_EXTRADATA_ENABLE *pParam =
4654                                       (QOMX_EXTRADATA_ENABLE *)paramData;
4655 
4656                                   if (m_state != OMX_StateLoaded) {
4657                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
4658                                       return OMX_ErrorIncorrectStateOperation;
4659                                   }
4660 
4661                                   if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4662                                       m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
4663                                   } else {
4664                                       DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
4665                                       eRet = OMX_ErrorUnsupportedIndex;
4666                                   }
4667                                   break;
4668                               }
4669         case OMX_IndexParamStandardComponentRole: {
4670                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
4671                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
4672                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
4673                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
4674                                           comp_role->cRole);
4675 
4676                                   if ((m_state == OMX_StateLoaded)&&
4677                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
4678                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
4679                                   } else {
4680                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4681                                       return OMX_ErrorIncorrectStateOperation;
4682                                   }
4683 
4684                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4685                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4686                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
4687                                       } else {
4688                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4689                                           eRet =OMX_ErrorUnsupportedSetting;
4690                                       }
4691                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4692                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4693                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
4694                                       } else {
4695                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4696                                           eRet = OMX_ErrorUnsupportedSetting;
4697                                       }
4698                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4699                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4700                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
4701                                       } else {
4702                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4703                                           eRet = OMX_ErrorUnsupportedSetting;
4704                                       }
4705                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
4706                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
4707                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4708                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
4709                                       } else {
4710                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4711                                           eRet = OMX_ErrorUnsupportedSetting;
4712                                       }
4713                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
4714                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
4715                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4716                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
4717                                       } else {
4718                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4719                                           eRet = OMX_ErrorUnsupportedSetting;
4720                                       }
4721                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4722                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4723                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4724                                       } else {
4725                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4726                                           eRet = OMX_ErrorUnsupportedSetting;
4727                                       }
4728                                   } else {
4729                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
4730                                       eRet = OMX_ErrorInvalidComponentName;
4731                                   }
4732                                   break;
4733                               }
4734 
4735         case OMX_IndexParamPriorityMgmt: {
4736                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
4737                              if (m_state != OMX_StateLoaded) {
4738                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4739                                  return OMX_ErrorIncorrectStateOperation;
4740                              }
4741                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
4742                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
4743                                      (unsigned int)priorityMgmtype->nGroupID);
4744 
4745                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
4746                                      (unsigned int)priorityMgmtype->nGroupPriority);
4747 
4748                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
4749                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
4750 
4751                              break;
4752                          }
4753 
4754         case OMX_IndexParamCompBufferSupplier: {
4755                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
4756                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
4757                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
4758                                            bufferSupplierType->eBufferSupplier);
4759                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
4760                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
4761 
4762                                    else
4763 
4764                                        eRet = OMX_ErrorBadPortIndex;
4765 
4766                                    break;
4767 
4768                                }
4769         case OMX_IndexParamVideoAvc: {
4770                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
4771                                      paramIndex);
4772                              break;
4773                          }
4774         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
4775                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
4776                                      paramIndex);
4777                              break;
4778                         }
4779         case OMX_IndexParamVideoMpeg2: {
4780                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
4781                                        paramIndex);
4782                                break;
4783                            }
4784         case OMX_QTIIndexParamLowLatencyMode: {
4785                                struct v4l2_control control;
4786                                int rc = 0;
4787                                QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE* pParam =
4788                                    (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
4789                                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
4790                                 if (pParam->bEnableLowLatencyMode)
4791                                     control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4792                                 else
4793                                     control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
4794 
4795                                 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4796                                 if (rc) {
4797                                     DEBUG_PRINT_ERROR("Set low latency failed");
4798                                     eRet = OMX_ErrorUnsupportedSetting;
4799                                 } else {
4800                                     m_sParamLowLatency.bEnableLowLatencyMode = pParam->bEnableLowLatencyMode;
4801                                 }
4802                                break;
4803                            }
4804         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
4805                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
4806                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
4807                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
4808                                      struct v4l2_control control;
4809                                      int pic_order,rc=0;
4810                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
4811                                              pictureOrder->eOutputPictureOrder);
4812                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
4813                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
4814                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
4815                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4816                                          time_stamp_dts.set_timestamp_reorder_mode(false);
4817                                      } else
4818                                          eRet = OMX_ErrorBadParameter;
4819                                      if (eRet == OMX_ErrorNone) {
4820                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4821                                          control.value = pic_order;
4822                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4823                                          if (rc) {
4824                                              DEBUG_PRINT_ERROR("Set picture order failed");
4825                                              eRet = OMX_ErrorUnsupportedSetting;
4826                                          }
4827                                      }
4828                                      m_decode_order_mode =
4829                                             pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
4830                                      break;
4831                                  }
4832         case OMX_QcomIndexParamConcealMBMapExtraData:
4833                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4834                                eRet = enable_extradata(OMX_MB_ERROR_MAP_EXTRADATA, false,
4835                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4836                                break;
4837         case OMX_QcomIndexParamFrameInfoExtraData:
4838                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4839                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
4840                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4841                                break;
4842         case OMX_ExtraDataFrameDimension:
4843                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4844                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
4845                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4846                                break;
4847         case OMX_QcomIndexParamInterlaceExtraData:
4848                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4849                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
4850                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4851                                break;
4852         case OMX_QcomIndexParamOutputCropExtraData:
4853                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4854                                eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4855                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4856                                break;
4857         case OMX_QcomIndexParamH264TimeInfo:
4858                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4859                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
4860                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4861                                break;
4862         case OMX_QcomIndexParamVideoFramePackingExtradata:
4863                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4864                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
4865                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4866                                break;
4867         case OMX_QcomIndexParamVideoQPExtraData:
4868                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4869                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
4870                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4871                                break;
4872         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
4873                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4874                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
4875                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
4876                                break;
4877         case OMX_QcomIndexEnableExtnUserData:
4878                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4879                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
4880                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
4881                                 break;
4882         case OMX_QTIIndexParamVQZipSEIExtraData:
4883                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4884                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
4885                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
4886                                 break;
4887         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
4888                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
4889                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
4890                                        struct v4l2_control control;
4891                                        int rc;
4892                                        drv_ctx.idr_only_decoding = 1;
4893                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4894                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4895                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4896                                        if (rc) {
4897                                            DEBUG_PRINT_ERROR("Set picture order failed");
4898                                            eRet = OMX_ErrorUnsupportedSetting;
4899                                        } else {
4900                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
4901                                            control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4902                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4903                                            if (rc) {
4904                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
4905                                                eRet = OMX_ErrorUnsupportedSetting;
4906                                            }
4907                                            /*Setting sync frame decoding on driver might change buffer
4908                                             * requirements so update them here*/
4909                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
4910                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
4911                                                eRet = OMX_ErrorUnsupportedSetting;
4912                                            }
4913                                            if (get_buffer_req(&drv_ctx.op_buf)) {
4914                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
4915                                                eRet = OMX_ErrorUnsupportedSetting;
4916                                            }
4917                                        }
4918                                    }
4919                                    break;
4920 
4921         case OMX_QcomIndexParamIndexExtraDataType: {
4922                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
4923                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
4924                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
4925                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
4926                                             (extradataIndexType->nPortIndex == 1)) {
4927                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
4928                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
4929                                     } else if ((extradataIndexType->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataOutputCropInfo) &&
4930                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
4931                                             (extradataIndexType->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)) {
4932                                         eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4933                                             ((QOMX_ENABLETYPE *)paramData)->bEnable);
4934                                     }
4935                                 }
4936                                 break;
4937         case OMX_QcomIndexParamEnableSmoothStreaming: {
4938 #ifndef SMOOTH_STREAMING_DISABLED
4939                                       eRet = enable_smoothstreaming();
4940 #else
4941                                       eRet = OMX_ErrorUnsupportedSetting;
4942 #endif
4943                                   }
4944                                   break;
4945 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4946                                   /* Need to allow following two set_parameters even in Idle
4947                                    * state. This is ANDROID architecture which is not in sync
4948                                    * with openmax standard. */
4949         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
4950                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
4951                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
4952                                            if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
4953                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
4954                                                 eRet = OMX_ErrorUnsupportedSetting;
4955                                                 break;
4956                                            } else if (m_out_mem_ptr) {
4957                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
4958                                                 eRet = OMX_ErrorInvalidState;
4959                                                 break;
4960                                            }
4961                                            if (enableNativeBuffers) {
4962                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
4963                                            }
4964 #if !defined(FLEXYUV_SUPPORTED)
4965                                            if (m_enable_android_native_buffers) {
4966                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
4967                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
4968                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
4969                                                    eRet = OMX_ErrorUnsupportedSetting;
4970                                                }
4971                                            }
4972 #endif
4973                                        }
4974                                        break;
4975         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
4976                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
4977                                        eRet = use_android_native_buffer(hComp, paramData);
4978                                    }
4979                                    break;
4980 #if ALLOCATE_OUTPUT_NATIVEHANDLE
4981         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
4982 
4983                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
4984                 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
4985 
4986                 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
4987                     DEBUG_PRINT_LOW("Enable/Disable allocate-native-handle allowed only on input port!. Please ignore this Unsupported Setting (0x80001019).");
4988                     eRet = OMX_ErrorUnsupportedSetting;
4989                     break;
4990                 } else if (m_inp_mem_ptr) {
4991                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
4992                     eRet = OMX_ErrorInvalidState;
4993                     break;
4994                 }
4995 
4996                 if (allocateNativeHandleParams != NULL) {
4997                     allocate_native_handle = allocateNativeHandleParams->enable;
4998                 }
4999             }
5000             break;
5001 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
5002 #endif
5003         case OMX_QcomIndexParamEnableTimeStampReorder: {
5004                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
5005                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
5006                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
5007                                            if (reorder->bEnable == OMX_TRUE) {
5008                                                frm_int =0;
5009                                                time_stamp_dts.set_timestamp_reorder_mode(true);
5010                                            } else
5011                                                time_stamp_dts.set_timestamp_reorder_mode(false);
5012                                        } else {
5013                                            time_stamp_dts.set_timestamp_reorder_mode(false);
5014                                            if (reorder->bEnable == OMX_TRUE) {
5015                                                eRet = OMX_ErrorUnsupportedSetting;
5016                                            }
5017                                        }
5018                                    }
5019                                    break;
5020         case OMX_IndexParamVideoProfileLevelCurrent: {
5021                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
5022                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
5023                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
5024                                      if (pParam) {
5025                                          m_profile_lvl.eProfile = pParam->eProfile;
5026                                          m_profile_lvl.eLevel = pParam->eLevel;
5027                                      }
5028                                      break;
5029 
5030                                  }
5031         case OMX_QcomIndexParamVideoMetaBufferMode:
5032         {
5033             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
5034             StoreMetaDataInBuffersParams *metabuffer =
5035                 (StoreMetaDataInBuffersParams *)paramData;
5036             if (!metabuffer) {
5037                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
5038                 eRet = OMX_ErrorBadParameter;
5039                 break;
5040             }
5041             if (m_disable_dynamic_buf_mode) {
5042                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
5043                 eRet = OMX_ErrorUnsupportedSetting;
5044                 break;
5045             }
5046             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
5047 
5048                 if (m_out_mem_ptr) {
5049                     DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
5050                     eRet = OMX_ErrorInvalidState;
5051                     break;
5052                 }
5053 
5054                 dynamic_buf_mode = metabuffer->bStoreMetaData;
5055                 DEBUG_PRINT_HIGH("%s buffer mode",
5056                     (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
5057 
5058             } else {
5059                 DEBUG_PRINT_ERROR(
5060                    "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
5061                    (unsigned int)metabuffer->nPortIndex);
5062                 eRet = OMX_ErrorUnsupportedSetting;
5063             }
5064             break;
5065         }
5066         case OMX_QcomIndexParamVideoDownScalar:
5067         {
5068             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
5069             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
5070             struct v4l2_control control;
5071             int rc;
5072             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
5073 
5074             if (pParam && pParam->bEnable) {
5075                 rc = enable_downscalar();
5076                 if (rc < 0) {
5077                     DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
5078                     return OMX_ErrorUnsupportedSetting;
5079                 }
5080                 m_force_down_scalar = pParam->bEnable;
5081             } else {
5082                 rc = disable_downscalar();
5083                 if (rc < 0) {
5084                     DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
5085                     return OMX_ErrorUnsupportedSetting;
5086                 }
5087                 m_force_down_scalar = pParam->bEnable;
5088             }
5089             break;
5090         }
5091 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5092         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
5093         {
5094             VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
5095             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
5096             PrepareForAdaptivePlaybackParams* pParams =
5097                     (PrepareForAdaptivePlaybackParams *) paramData;
5098             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
5099                 if (!pParams->bEnable) {
5100                     return OMX_ErrorNone;
5101                 }
5102                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
5103                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
5104                     DEBUG_PRINT_ERROR(
5105                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
5106                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
5107                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
5108                     eRet = OMX_ErrorBadParameter;
5109                 } else {
5110                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
5111                 }
5112             } else {
5113                 DEBUG_PRINT_ERROR(
5114                         "Prepare for adaptive playback supported only on output port");
5115                 eRet = OMX_ErrorBadParameter;
5116             }
5117             break;
5118         }
5119 
5120         case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
5121         {
5122             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5123             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
5124             m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5125             if (m_disable_dynamic_buf_mode) {
5126                 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
5127             }
5128             break;
5129         }
5130 #endif
5131         case OMX_QcomIndexParamVideoCustomBufferSize:
5132         {
5133             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
5134             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
5135             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
5136             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5137                 struct v4l2_control control;
5138                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
5139                 control.value = pParam->nBufferSize;
5140                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5141                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
5142                     eRet = OMX_ErrorUnsupportedSetting;
5143                 } else {
5144                     eRet = get_buffer_req(&drv_ctx.ip_buf);
5145                     if (eRet == OMX_ErrorNone) {
5146                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
5147                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
5148                             m_custom_buffersize.input_buffersize);
5149                     } else {
5150                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
5151                     }
5152                 }
5153             } else {
5154                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
5155                 eRet = OMX_ErrorBadParameter;
5156             }
5157             break;
5158         }
5159         case OMX_QTIIndexParamVQZIPSEIType:
5160         {
5161             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
5162             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
5163             OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
5164                 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
5165                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
5166 
5167             eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
5168                 ((QOMX_ENABLETYPE *)paramData)->bEnable);
5169             if (eRet != OMX_ErrorNone) {
5170                 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
5171                 eRet = OMX_ErrorBadParameter;
5172                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5173                 break;
5174             }
5175             eRet = enable_extradata(OMX_QP_EXTRADATA, false,
5176                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
5177             if (eRet != OMX_ErrorNone) {
5178                 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
5179                 eRet = OMX_ErrorBadParameter;
5180                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5181                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5182                 break;
5183             }
5184             eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
5185                         ((QOMX_ENABLETYPE *)paramData)->bEnable);
5186             if (eRet != OMX_ErrorNone) {
5187                 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata");
5188                 eRet = OMX_ErrorBadParameter;
5189                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5190                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5191                 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA;
5192             }
5193             break;
5194         }
5195         case OMX_QTIIndexParamPassInputBufferFd:
5196         {
5197             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5198             if (arbitrary_bytes) {
5199                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
5200                 eRet = OMX_ErrorUnsupportedSetting;
5201                 break;
5202             }
5203 
5204             m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5205             if (m_input_pass_buffer_fd)
5206                 DEBUG_PRINT_LOW("Enable passing input buffer FD");
5207             break;
5208         }
5209         case OMX_QTIIndexParamForceCompressedForDPB:
5210         {
5211             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
5212             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
5213             OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
5214                 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
5215             if (m_disable_ubwc_mode) {
5216                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
5217                 eRet = OMX_ErrorUnsupportedSetting;
5218                 break;
5219             }
5220             if (!paramData) {
5221                DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
5222                eRet = OMX_ErrorBadParameter;
5223                break;
5224             }
5225 
5226             m_force_compressed_for_dpb = pParam->bEnable;
5227             break;
5228         }
5229         case OMX_QTIIndexParamForceUnCompressedForOPB:
5230         {
5231             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
5232             OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
5233                 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
5234             if (!paramData) {
5235                 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
5236                 eRet = OMX_ErrorBadParameter;
5237                 break;
5238             }
5239             m_disable_ubwc_mode = pParam->bEnable;
5240             DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
5241             break;
5242         }
5243         case OMX_QTIIndexParamDitherControl:
5244         {
5245             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
5246             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl");
5247             QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData;
5248             DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType);
5249             if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) ||
5250                 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) {
5251                 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range");
5252                 eRet = OMX_ErrorBadParameter;
5253                 break;
5254             }
5255             m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE;
5256             DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config);
5257             break;
5258         }
5259         case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
5260         {
5261             VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
5262             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
5263             OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
5264 
5265             if ((output_capability != V4L2_PIX_FMT_H264) ||
5266                 (output_capability != V4L2_PIX_FMT_HEVC)) {
5267                 DEBUG_PRINT_ERROR("set_parameter: Unsupported codec for client configured profile and level");
5268                 eRet = OMX_ErrorBadParameter;
5269             }
5270 
5271             DEBUG_PRINT_LOW("set_parameter: Client set profile is: %d", pParam->eProfile);
5272             DEBUG_PRINT_LOW("set_parameter: Client set level is: %d", pParam->eLevel);
5273             mClientSessionForSufficiency = true;
5274             mClientSetProfile = pParam->eProfile;
5275             mClientSetLevel = pParam->eLevel;
5276             break;
5277         }
5278         case OMX_QTIIndexParamVideoDecoderOutputFrameRate:
5279         {
5280             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_OUTPUT_FRAME_RATE);
5281             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoDecoderOutputFrameRate");
5282             QOMX_VIDEO_OUTPUT_FRAME_RATE *pParam = (QOMX_VIDEO_OUTPUT_FRAME_RATE*)paramData;
5283             DEBUG_PRINT_LOW("set_parameter: decoder output-frame-rate %d", pParam->fps);
5284             m_dec_hfr_fps=pParam->fps;
5285             DEBUG_PRINT_HIGH("output-frame-rate value = %d", m_dec_hfr_fps);
5286             if (m_dec_hfr_fps) {
5287                 m_last_rendered_TS = 0;
5288             }
5289             break;
5290         }
5291         default: {
5292                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
5293                  eRet = OMX_ErrorUnsupportedIndex;
5294              }
5295     }
5296     if (eRet != OMX_ErrorNone)
5297         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
5298     return eRet;
5299 }
5300 
5301 /* ======================================================================
5302    FUNCTION
5303    omx_vdec::GetConfig
5304 
5305    DESCRIPTION
5306    OMX Get Config Method implementation.
5307 
5308    PARAMETERS
5309    <TBD>.
5310 
5311    RETURN VALUE
5312    OMX Error None if successful.
5313 
5314    ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)5315 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
5316         OMX_IN OMX_INDEXTYPE configIndex,
5317         OMX_INOUT OMX_PTR     configData)
5318 {
5319     (void) hComp;
5320     OMX_ERRORTYPE eRet = OMX_ErrorNone;
5321 
5322     if (m_state == OMX_StateInvalid) {
5323         DEBUG_PRINT_ERROR("Get Config in Invalid State");
5324         return OMX_ErrorInvalidState;
5325     }
5326 
5327     switch ((unsigned long)configIndex) {
5328         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
5329                                      VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
5330                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
5331                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
5332                                      decoderinstances->nNumOfInstances = 16;
5333                                      /*TODO: How to handle this case */
5334                                      break;
5335                                  }
5336         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
5337                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
5338                                               VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
5339                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
5340                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
5341                                               memcpy(configFmt, &m_frame_pack_arrangement,
5342                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
5343                                           } else {
5344                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
5345                                           }
5346                                           break;
5347                                       }
5348         case OMX_IndexConfigCommonOutputCrop: {
5349                                   VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
5350                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
5351                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
5352                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
5353                                         rectangle.nLeft, rectangle.nTop,
5354                                         rectangle.nWidth, rectangle.nHeight);
5355                                   break;
5356                               }
5357         case OMX_QcomIndexConfigH264EntropyCodingCabac: {
5358             VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
5359             QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
5360             struct v4l2_control control;
5361 
5362             if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
5363                 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
5364                 eRet = OMX_ErrorNotImplemented;
5365                 break;
5366             }
5367 
5368             control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
5369             if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
5370                 coding->bCabac = (OMX_BOOL)
5371                     (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
5372                 /* We can't query driver at the moment for the cabac mode, so
5373                  * just use 0xff...f as a place holder for future improvement */
5374                 coding->nCabacInitIdc = ~0;
5375             } else {
5376                 eRet = OMX_ErrorUnsupportedIndex;
5377             }
5378 
5379             break;
5380         }
5381         case OMX_QTIIndexConfigDescribeColorAspects:
5382         {
5383             VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5384             DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5385 
5386             if (params->bRequestingDataSpace) {
5387                 DEBUG_PRINT_LOW("Does not handle dataspace request. Please ignore this Unsupported Setting (0x80001019).");
5388                 return OMX_ErrorUnsupportedSetting;
5389             }
5390 
5391             print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
5392             print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
5393             get_preferred_color_aspects(params->sAspects);
5394             print_debug_color_aspects(&(params->sAspects), "Frameworks path GetConfig Color Aspects");
5395 
5396             break;
5397         }
5398         case OMX_QTIIndexConfigDescribeHDRColorInfo:
5399         {
5400             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5401             DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5402             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR");
5403             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR");
5404             get_preferred_hdr_info(params->sInfo);
5405             print_debug_hdr_color_info(&(params->sInfo), "Frameworks path GetConfig HDR");
5406 
5407             break;
5408         }
5409         case OMX_QTIIndexConfigDescribeHDR10PlusInfo:
5410         {
5411             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
5412             DescribeHDR10PlusInfoParams *params = (DescribeHDR10PlusInfoParams *)configData;
5413             get_hdr10plusinfo(params);
5414             print_hdr10plusinfo(params);
5415             break;
5416         }
5417         case OMX_IndexConfigAndroidVendorExtension:
5418         {
5419             VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5420 
5421             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5422                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5423             VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5424             return get_vendor_extension_config(ext);
5425         }
5426         default:
5427         {
5428             DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
5429             eRet = OMX_ErrorBadParameter;
5430         }
5431 
5432     }
5433 
5434     return eRet;
5435 }
5436 
5437 /* ======================================================================
5438    FUNCTION
5439    omx_vdec::SetConfig
5440 
5441    DESCRIPTION
5442    OMX Set Config method implementation
5443 
5444    PARAMETERS
5445    <TBD>.
5446 
5447    RETURN VALUE
5448    OMX Error None if successful.
5449    ========================================================================== */
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)5450 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
5451         OMX_IN OMX_INDEXTYPE configIndex,
5452         OMX_IN OMX_PTR        configData)
5453 {
5454     (void) hComp;
5455     if (m_state == OMX_StateInvalid) {
5456         DEBUG_PRINT_ERROR("Get Config in Invalid State");
5457         return OMX_ErrorInvalidState;
5458     }
5459 
5460     OMX_ERRORTYPE ret = OMX_ErrorNone;
5461     OMX_VIDEO_CONFIG_NALSIZE *pNal;
5462 
5463     DEBUG_PRINT_LOW("Set Config Called");
5464 
5465 
5466     if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
5467         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
5468         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
5469 
5470         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5471             if (config->bEnabled) {
5472                 if ((config->nFps >> 16) > 0 &&
5473                         (config->nFps >> 16) <= MAX_SUPPORTED_FPS) {
5474                     m_fps_received = config->nFps;
5475                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
5476                             (unsigned int)config->nFps >> 16);
5477                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
5478                             drv_ctx.frame_rate.fps_denominator);
5479 
5480                     if (!drv_ctx.frame_rate.fps_numerator) {
5481                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
5482                         drv_ctx.frame_rate.fps_numerator = 30;
5483                     }
5484 
5485                     if (drv_ctx.frame_rate.fps_denominator) {
5486                         drv_ctx.frame_rate.fps_numerator = (int)
5487                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
5488                     }
5489 
5490                     drv_ctx.frame_rate.fps_denominator = 1;
5491                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
5492                         drv_ctx.frame_rate.fps_numerator;
5493 
5494                     struct v4l2_outputparm oparm;
5495                     /*XXX: we're providing timing info as seconds per frame rather than frames
5496                      * per second.*/
5497                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
5498                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
5499 
5500                     struct v4l2_streamparm sparm;
5501                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5502                     sparm.parm.output = oparm;
5503                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
5504                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
5505                                 performance might be affected");
5506                         ret = OMX_ErrorHardware;
5507                     }
5508                     client_set_fps = true;
5509                 } else {
5510                     DEBUG_PRINT_ERROR("Frame rate not supported.");
5511                     ret = OMX_ErrorUnsupportedSetting;
5512                 }
5513             } else {
5514                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
5515                 client_set_fps = false;
5516             }
5517         } else {
5518             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
5519                     (int)config->nPortIndex);
5520             ret = OMX_ErrorBadPortIndex;
5521         }
5522 
5523         return ret;
5524     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
5525         OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
5526             (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
5527         struct v4l2_control control;
5528         DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
5529         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
5530 
5531         switch (config->eDecodeType) {
5532             case OMX_QCOM_PictypeDecode_I:
5533                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I;
5534                 break;
5535             case OMX_QCOM_PictypeDecode_IPB:
5536             default:
5537                 control.value = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I|
5538                                   V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P|
5539                                   V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B);
5540                 break;
5541         }
5542 
5543         ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
5544                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
5545         if (ret)
5546             DEBUG_PRINT_ERROR("Failed to set picture type decode");
5547 
5548         return ret;
5549     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
5550         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
5551         DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
5552 
5553         struct v4l2_control control;
5554 
5555         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
5556         if (priority->nU32 == 0)
5557             control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
5558         else
5559             control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
5560 
5561         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5562             DEBUG_PRINT_ERROR("Failed to set Priority");
5563             ret = OMX_ErrorUnsupportedSetting;
5564         }
5565         return ret;
5566     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
5567         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
5568         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
5569 
5570         struct v4l2_control control;
5571 
5572         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
5573         control.value = rate->nU32;
5574 
5575         if (rate->nU32 == QOMX_VIDEO_HIGH_PERF_OPERATING_MODE) {
5576             DEBUG_PRINT_LOW("Turbo mode requested");
5577             m_client_req_turbo_mode = true;
5578         } else {
5579             operating_frame_rate = rate->nU32 >> 16;
5580             m_client_req_turbo_mode = false;
5581             DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  operating_frame_rate);
5582         }
5583 
5584         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5585             ret = errno == EBUSY ? OMX_ErrorInsufficientResources :
5586                     OMX_ErrorUnsupportedSetting;
5587             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
5588                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
5589         }
5590         return ret;
5591 
5592     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
5593         VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5594         DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5595         if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
5596             enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, false, true);
5597         }
5598 
5599         print_debug_color_aspects(&(params->sAspects), "Set Config");
5600         memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
5601         return ret;
5602     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) {
5603         VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5604         DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5605         ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, false, true);
5606         if (ret != OMX_ErrorNone) {
5607             DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA");
5608             return ret;
5609         }
5610 
5611         print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR");
5612         memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams));
5613         return ret;
5614 
5615     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDR10PlusInfo) {
5616         VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
5617         if (!store_vp9_hdr10plusinfo((DescribeHDR10PlusInfoParams *)configData)) {
5618             DEBUG_PRINT_ERROR("Failed to set hdr10plus info");
5619         }
5620         return ret;
5621 
5622     } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
5623         VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5624 
5625         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5626                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5627         VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5628 
5629         return set_vendor_extension_config(ext);
5630     }  else if ((int)configIndex == (int)OMX_IndexConfigLowLatency) {
5631         OMX_CONFIG_BOOLEANTYPE *lowLatency = (OMX_CONFIG_BOOLEANTYPE *)configData;
5632         DEBUG_PRINT_LOW("Set_config: low-latency %u",(uint32_t)lowLatency->bEnabled);
5633         struct v4l2_control control;
5634         control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
5635         if (lowLatency->bEnabled) {
5636             control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
5637         } else {
5638             control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
5639         }
5640         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5641             DEBUG_PRINT_ERROR("Set low latency failed");
5642             ret = OMX_ErrorUnsupportedSetting;
5643         } else {
5644             m_sParamLowLatency.bEnableLowLatencyMode = lowLatency->bEnabled;
5645         }
5646         return ret;
5647     }
5648 
5649     return OMX_ErrorNotImplemented;
5650 }
5651 
5652 #define extn_equals(param, extn) (!strcmp(param, extn))
5653 
5654 /* ======================================================================
5655    FUNCTION
5656    omx_vdec::GetExtensionIndex
5657 
5658    DESCRIPTION
5659    OMX GetExtensionIndex method implementaion.  <TBD>
5660 
5661    PARAMETERS
5662    <TBD>.
5663 
5664    RETURN VALUE
5665    OMX Error None if everything successful.
5666 
5667    ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)5668 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
5669         OMX_IN OMX_STRING      paramName,
5670         OMX_OUT OMX_INDEXTYPE* indexType)
5671 {
5672     (void) hComp;
5673     if (m_state == OMX_StateInvalid) {
5674         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
5675         return OMX_ErrorInvalidState;
5676     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
5677         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
5678     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
5679         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
5680     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
5681         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
5682     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
5683         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
5684     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
5685         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
5686     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
5687         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
5688     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
5689         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
5690     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNOUTPUTCROP_EXTRADATA)) {
5691         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamOutputCropExtraData;
5692     }
5693 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
5694     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
5695         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
5696     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
5697         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
5698     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
5699         DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
5700         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
5701     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
5702         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
5703     }
5704 #if ALLOCATE_OUTPUT_NATIVEHANDLE
5705     else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
5706         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
5707     }
5708 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
5709 #endif
5710     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
5711         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
5712     }
5713 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5714     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
5715         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
5716     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
5717         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
5718     }
5719 #endif
5720 #ifdef FLEXYUV_SUPPORTED
5721     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
5722         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
5723     }
5724 #endif
5725     else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
5726         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
5727     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
5728         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
5729     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
5730         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
5731     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
5732         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
5733     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
5734         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
5735     } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
5736         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
5737     } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) {
5738         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo;
5739     } else if (extn_equals(paramName, "OMX.QTI.index.param.ClientConfiguredProfileLevel")) {
5740         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency;
5741     } else if (extn_equals(paramName, "OMX.google.android.index.describeHDR10PlusInfo")) {
5742         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDR10PlusInfo;
5743     }else {
5744         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
5745         return OMX_ErrorNotImplemented;
5746     }
5747     return OMX_ErrorNone;
5748 }
5749 
5750 /* ======================================================================
5751    FUNCTION
5752    omx_vdec::GetState
5753 
5754    DESCRIPTION
5755    Returns the state information back to the caller.<TBD>
5756 
5757    PARAMETERS
5758    <TBD>.
5759 
5760    RETURN VALUE
5761    Error None if everything is successful.
5762    ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)5763 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
5764         OMX_OUT OMX_STATETYPE* state)
5765 {
5766     (void) hComp;
5767     *state = m_state;
5768     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
5769     return OMX_ErrorNone;
5770 }
5771 
5772 /* ======================================================================
5773    FUNCTION
5774    omx_vdec::ComponentTunnelRequest
5775 
5776    DESCRIPTION
5777    OMX Component Tunnel Request method implementation. <TBD>
5778 
5779    PARAMETERS
5780    None.
5781 
5782    RETURN VALUE
5783    OMX Error None if everything successful.
5784 
5785    ========================================================================== */
component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_HANDLETYPE peerComponent,OMX_IN OMX_U32 peerPort,OMX_INOUT OMX_TUNNELSETUPTYPE * tunnelSetup)5786 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
5787         OMX_IN OMX_U32                        port,
5788         OMX_IN OMX_HANDLETYPE        peerComponent,
5789         OMX_IN OMX_U32                    peerPort,
5790         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
5791 {
5792     (void) hComp;
5793     (void) port;
5794     (void) peerComponent;
5795     (void) peerPort;
5796     (void) tunnelSetup;
5797     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
5798     return OMX_ErrorNotImplemented;
5799 }
5800 
5801 
5802 
5803 /* ======================================================================
5804    FUNCTION
5805    omx_vdec::ion_map
5806 
5807    DESCRIPTION
5808    Map the memory and run the ioctl SYNC operations
5809    on ION fd with DMA_BUF_IOCTL_SYNC
5810 
5811    PARAMETERS
5812    fd    : ION fd
5813    len   : Lenth of the memory
5814 
5815    RETURN VALUE
5816    ERROR: mapped memory pointer
5817 
5818    ========================================================================== */
ion_map(int fd,int len)5819 char *omx_vdec::ion_map(int fd, int len)
5820 {
5821     char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
5822                                 MAP_SHARED, fd, 0);
5823     if (bufaddr != MAP_FAILED) {
5824 #ifdef USE_ION
5825     do_cache_operations(fd);
5826 #endif
5827     }
5828     return bufaddr;
5829 }
5830 
5831 /* ======================================================================
5832    FUNCTION
5833    omx_vdec::ion_unmap
5834 
5835    DESCRIPTION
5836    Unmap the memory
5837 
5838    PARAMETERS
5839    fd      : ION fd
5840    bufaddr : buffer address
5841    len     : Lenth of the memory
5842 
5843    RETURN VALUE
5844    OMX_Error*
5845 
5846    ========================================================================== */
ion_unmap(int fd,void * bufaddr,int len)5847 OMX_ERRORTYPE omx_vdec::ion_unmap(int fd, void *bufaddr, int len)
5848 {
5849 #ifdef USE_ION
5850     do_cache_operations(fd);
5851 #else
5852     (void)fd;
5853 #endif
5854     if (-1 == munmap(bufaddr, len)) {
5855         DEBUG_PRINT_ERROR("munmap failed.");
5856         return OMX_ErrorInsufficientResources;
5857     }
5858     return OMX_ErrorNone;
5859 }
5860 
5861 /* ======================================================================
5862    FUNCTION
5863    omx_vdec::UseOutputBuffer
5864 
5865    DESCRIPTION
5866    Helper function for Use buffer in the input pin
5867 
5868    PARAMETERS
5869    None.
5870 
5871    RETURN VALUE
5872    true/false
5873 
5874    ========================================================================== */
allocate_extradata()5875 OMX_ERRORTYPE omx_vdec::allocate_extradata()
5876 {
5877 #ifdef USE_ION
5878     if (drv_ctx.extradata_info.buffer_size) {
5879         if (drv_ctx.extradata_info.ion.data_fd >= 0) {
5880             free_extradata();
5881         }
5882 
5883         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
5884         // Decoder extradata is always uncached as buffer sizes are very small
5885         bool status = alloc_map_ion_memory(
5886                 drv_ctx.extradata_info.size, &drv_ctx.extradata_info.ion, 0);
5887         if (status == false) {
5888             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
5889             return OMX_ErrorInsufficientResources;
5890         }
5891         DEBUG_PRINT_HIGH("Allocated extradata size : %d fd: %d",
5892             drv_ctx.extradata_info.size, drv_ctx.extradata_info.ion.data_fd);
5893         drv_ctx.extradata_info.uaddr = ion_map(drv_ctx.extradata_info.ion.data_fd,
5894                                                drv_ctx.extradata_info.size);
5895         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
5896             DEBUG_PRINT_ERROR("Failed to map extradata memory");
5897             free_ion_memory(&drv_ctx.extradata_info.ion);
5898             return OMX_ErrorInsufficientResources;
5899         }
5900     }
5901 #endif
5902     return OMX_ErrorNone;
5903 }
5904 
free_extradata()5905 void omx_vdec::free_extradata()
5906 {
5907 #ifdef USE_ION
5908     if (drv_ctx.extradata_info.uaddr) {
5909         ion_unmap(drv_ctx.extradata_info.ion.data_fd,
5910                   (void *)drv_ctx.extradata_info.uaddr,
5911                   drv_ctx.extradata_info.ion.alloc_data.len);
5912         free_ion_memory(&drv_ctx.extradata_info.ion);
5913         drv_ctx.extradata_info.uaddr = NULL;
5914         drv_ctx.extradata_info.ion.data_fd = -1;
5915     }
5916 #endif
5917 }
5918 
use_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)5919 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
5920         OMX_IN OMX_HANDLETYPE            hComp,
5921         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5922         OMX_IN OMX_U32                   port,
5923         OMX_IN OMX_PTR                   appData,
5924         OMX_IN OMX_U32                   bytes,
5925         OMX_IN OMX_U8*                   buffer)
5926 {
5927     OMX_ERRORTYPE eRet = OMX_ErrorNone;
5928     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
5929     unsigned                         i= 0; // Temporary counter
5930     OMX_PTR privateAppData = NULL;
5931     private_handle_t *handle = NULL;
5932     OMX_U8 *buff = buffer;
5933     bool intermediate = client_buffers.is_color_conversion_enabled();
5934     (void) hComp;
5935     (void) port;
5936 
5937     if (!m_out_mem_ptr) {
5938         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers C2D(%d)",
5939                          client_buffers.is_color_conversion_enabled());
5940         eRet = allocate_output_headers();
5941         if (eRet == OMX_ErrorNone)
5942             eRet = allocate_extradata();
5943         output_use_buffer = true;
5944     }
5945 
5946     OMX_BUFFERHEADERTYPE  **omx_base_address =
5947         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
5948 
5949     if (eRet == OMX_ErrorNone) {
5950         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5951             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
5952                 break;
5953             }
5954         }
5955     }
5956 
5957     if (i >= drv_ctx.op_buf.actualcount) {
5958         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
5959         return OMX_ErrorInsufficientResources;
5960     }
5961 
5962     if (intermediate) {
5963         DEBUG_PRINT_HIGH("Use_op_buf:Allocating intermediate output. %d", i);
5964         OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
5965         eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
5966                                       port, appData,
5967                                       drv_ctx.op_buf.buffer_size,
5968                                       true, i);
5969     }
5970 
5971     if (eRet == OMX_ErrorNone && dynamic_buf_mode) {
5972         *bufferHdr = (m_out_mem_ptr + i );
5973         (*bufferHdr)->pBuffer = NULL;
5974         if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
5975             enum v4l2_buf_type buf_type;
5976             int rr = 0;
5977             DEBUG_PRINT_LOW("USE intermediate bufferSTREAMON(CAPTURE_MPLANE)");
5978             set_buffer_req(&drv_ctx.op_buf);
5979             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5980             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
5981                 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
5982                 return OMX_ErrorInsufficientResources;
5983             } else {
5984                 streaming[CAPTURE_PORT] = true;
5985                 DEBUG_PRINT_LOW("STREAMON Successful");
5986             }
5987         }
5988         BITMASK_SET(&m_out_bm_count,i);
5989         (*bufferHdr)->pAppPrivate = appData;
5990         (*bufferHdr)->pBuffer = buffer;
5991         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
5992         return eRet;
5993     }
5994 
5995     if (eRet == OMX_ErrorNone) {
5996 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
5997         if (m_enable_android_native_buffers) {
5998             if (m_use_android_native_buffers) {
5999                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
6000                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
6001                 handle = (private_handle_t *)nBuf->handle;
6002                 privateAppData = params->pAppPrivate;
6003             } else {
6004                 handle = (private_handle_t *)buff;
6005                 privateAppData = appData;
6006             }
6007             if (!handle) {
6008                 DEBUG_PRINT_ERROR("handle is invalid");
6009                 return OMX_ErrorBadParameter;
6010             }
6011 
6012             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
6013                 if (secure_mode && secure_scaling_to_non_secure_opb) {
6014                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
6015                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
6016                 } else {
6017                     DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
6018                             " expected %u, got %u",
6019                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
6020                     return OMX_ErrorBadParameter;
6021                 }
6022             }
6023 
6024             drv_ctx.op_buf.buffer_size = handle->size;
6025 
6026             if (!m_use_android_native_buffers) {
6027                 if (!secure_mode) {
6028                     buff = (OMX_U8*)ion_map(handle->fd, handle->size);
6029                     if (buff == MAP_FAILED) {
6030                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
6031                         return OMX_ErrorInsufficientResources;
6032                     }
6033                 }
6034             }
6035 #if defined(_ANDROID_ICS_)
6036             native_buffer[i].nativehandle = handle;
6037             native_buffer[i].privatehandle = handle;
6038 #endif
6039             if (!handle) {
6040                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
6041                 return OMX_ErrorBadParameter;
6042             }
6043             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
6044             drv_ctx.ptr_outputbuffer[i].offset = 0;
6045             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
6046             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
6047             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
6048         } else
6049 #endif
6050             if (!ouput_egl_buffers && !m_use_output_pmem) {
6051 #ifdef USE_GBM
6052                bool status = alloc_map_gbm_memory(
6053                        drv_ctx.video_resolution.frame_width,
6054                        drv_ctx.video_resolution.frame_height,
6055                        drv_ctx.gbm_device_fd,
6056                        &drv_ctx.op_buf_gbm_info[i],
6057                        secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
6058                 if (status == false) {
6059                     DEBUG_PRINT_ERROR("ION device fd is bad %d",
6060                                       (int) drv_ctx.op_buf_ion_info[i].data_fd);
6061                     return OMX_ErrorInsufficientResources;
6062                 }
6063                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
6064                                      drv_ctx.op_buf_gbm_info[i].bo_fd;
6065                 if (intermediate)
6066                    m_pmem_info[i].pmeta_fd = drv_ctx.op_buf_gbm_info[i].meta_fd;
6067 #elif defined USE_ION
6068                 bool status = alloc_map_ion_memory(
6069                         drv_ctx.op_buf.buffer_size, &drv_ctx.op_buf_ion_info[i],
6070                         secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
6071                 if (status == false) {
6072                     DEBUG_PRINT_ERROR("ION device fd is bad %d",
6073                                       (int) drv_ctx.op_buf_ion_info[i].data_fd);
6074                     return OMX_ErrorInsufficientResources;
6075                 }
6076                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
6077                                      drv_ctx.op_buf_ion_info[i].data_fd;
6078 #endif
6079                 if (!secure_mode) {
6080                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
6081                         (unsigned char *)ion_map(drv_ctx.ptr_outputbuffer[i].pmem_fd,
6082                                                  drv_ctx.op_buf.buffer_size);
6083                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
6084 #ifdef USE_GBM
6085                         free_gbm_memory(&drv_ctx.op_buf_gbm_info[i]);
6086 #elif defined USE_ION
6087                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
6088 #endif
6089                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
6090                         return OMX_ErrorInsufficientResources;
6091                     }
6092                 }
6093                 drv_ctx.ptr_outputbuffer[i].offset = 0;
6094                 privateAppData = appData;
6095             } else {
6096                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
6097                 if (!appData || !bytes ) {
6098                     if (!secure_mode && !buffer) {
6099                         DEBUG_PRINT_ERROR("Bad parameters for use buffer");
6100                         return OMX_ErrorBadParameter;
6101                     }
6102                 }
6103 
6104                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
6105                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
6106                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
6107                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
6108                         !pmem_list->nEntries ||
6109                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
6110                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
6111                     return OMX_ErrorBadParameter;
6112                 }
6113                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6114                     pmem_list->entryList->entry;
6115                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
6116                         pmem_info->pmem_fd);
6117                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
6118 #ifdef USE_GBM
6119                 if (intermediate)
6120                    m_pmem_info[i].pmeta_fd = pmem_info->pmeta_fd;
6121 #endif
6122                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
6123                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
6124                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
6125                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
6126                 privateAppData = appData;
6127             }
6128         if (intermediate) {
6129             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
6130             m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
6131             m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
6132             m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
6133             m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
6134         }
6135         *bufferHdr = (m_out_mem_ptr + i );
6136 
6137         if (secure_mode)
6138             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
6139 
6140         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
6141             enum v4l2_buf_type buf_type;
6142             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6143             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
6144                 return OMX_ErrorInsufficientResources;
6145             } else {
6146                 streaming[CAPTURE_PORT] = true;
6147                 DEBUG_PRINT_LOW("STREAMON Successful");
6148             }
6149         }
6150 
6151         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
6152         if (m_enable_android_native_buffers) {
6153             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
6154             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
6155         } else {
6156             (*bufferHdr)->pBuffer = buff;
6157         }
6158         (*bufferHdr)->pAppPrivate = privateAppData;
6159         BITMASK_SET(&m_out_bm_count,i);
6160     }
6161     return eRet;
6162 }
6163 
allocate_client_output_extradata_headers()6164 OMX_ERRORTYPE omx_vdec::allocate_client_output_extradata_headers() {
6165     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6166     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
6167     int i = 0;
6168 
6169     if (!m_client_output_extradata_mem_ptr) {
6170         int nBufferCount       = 0;
6171 
6172         nBufferCount = m_client_out_extradata_info.getBufferCount();
6173         DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount);
6174 
6175         m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
6176 
6177         if (m_client_output_extradata_mem_ptr) {
6178             bufHdr          =  m_client_output_extradata_mem_ptr;
6179             for (i=0; i < nBufferCount; i++) {
6180                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
6181                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
6182                 // Set the values when we determine the right HxW param
6183                 bufHdr->nAllocLen          = 0;
6184                 bufHdr->nFilledLen         = 0;
6185                 bufHdr->pAppPrivate        = NULL;
6186                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_EXTRADATA_INDEX;
6187                 bufHdr->pBuffer            = NULL;
6188                 bufHdr->pOutputPortPrivate = NULL;
6189                 bufHdr++;
6190             }
6191         } else {
6192              DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
6193                     m_client_output_extradata_mem_ptr);
6194               eRet =  OMX_ErrorInsufficientResources;
6195         }
6196     }
6197     return eRet;
6198 }
use_client_output_extradata_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)6199 OMX_ERRORTYPE  omx_vdec::use_client_output_extradata_buffer(
6200         OMX_IN OMX_HANDLETYPE            hComp,
6201         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6202         OMX_IN OMX_U32                   port,
6203         OMX_IN OMX_PTR                   appData,
6204         OMX_IN OMX_U32                   bytes,
6205         OMX_IN OMX_U8*                   buffer)
6206 {
6207     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6208     unsigned i = 0; // Temporary counter
6209     unsigned buffer_count = m_client_out_extradata_info.getBufferCount();;
6210     OMX_U32 buffer_size = m_client_out_extradata_info.getSize();
6211     (void) hComp;
6212 
6213     if (port != OMX_CORE_OUTPUT_EXTRADATA_INDEX ||
6214             !client_extradata || bytes != buffer_size|| bufferHdr == NULL) {
6215         DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
6216             "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
6217             OMX_CORE_OUTPUT_EXTRADATA_INDEX, client_extradata, bytes, buffer_size, bufferHdr);
6218         eRet = OMX_ErrorBadParameter;
6219         return eRet;
6220     }
6221 
6222     if (!m_client_output_extradata_mem_ptr) {
6223         eRet = allocate_client_output_extradata_headers();
6224     }
6225 
6226     if (eRet == OMX_ErrorNone) {
6227         for (i = 0; i < buffer_count; i++) {
6228             if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) {
6229                 break;
6230             }
6231         }
6232     }
6233 
6234     if (i >= buffer_count) {
6235         DEBUG_PRINT_ERROR("Already using %d Extradata o/p buffers", buffer_count);
6236         eRet = OMX_ErrorInsufficientResources;
6237     }
6238 
6239     if (eRet == OMX_ErrorNone) {
6240         BITMASK_SET(&m_out_extradata_bm_count,i);
6241         *bufferHdr = (m_client_output_extradata_mem_ptr + i );
6242         (*bufferHdr)->pAppPrivate = appData;
6243         (*bufferHdr)->pBuffer = buffer;
6244         (*bufferHdr)->nAllocLen = bytes;
6245     }
6246 
6247     return eRet;
6248 }
6249 /* ======================================================================
6250    FUNCTION
6251    omx_vdec::use_input_heap_buffers
6252 
6253    DESCRIPTION
6254    OMX Use Buffer Heap allocation method implementation.
6255 
6256    PARAMETERS
6257    <TBD>.
6258 
6259    RETURN VALUE
6260    OMX Error None , if everything successful.
6261 
6262    ========================================================================== */
use_input_heap_buffers(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)6263 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
6264         OMX_IN OMX_HANDLETYPE            hComp,
6265         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6266         OMX_IN OMX_U32                   port,
6267         OMX_IN OMX_PTR                   appData,
6268         OMX_IN OMX_U32                   bytes,
6269         OMX_IN OMX_U8*                   buffer)
6270 {
6271     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
6272     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6273 
6274     if (secure_mode) {
6275         DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
6276         return OMX_ErrorUndefined;
6277     }
6278 
6279     if (!m_inp_heap_ptr)
6280         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
6281             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6282                     drv_ctx.ip_buf.actualcount);
6283     if (!m_phdr_pmem_ptr)
6284         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
6285             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6286                     drv_ctx.ip_buf.actualcount);
6287     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
6288         DEBUG_PRINT_ERROR("Insufficent memory");
6289         eRet = OMX_ErrorInsufficientResources;
6290     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
6291         input_use_buffer = true;
6292         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
6293         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
6294         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
6295         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
6296         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
6297         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
6298         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
6299         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
6300         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
6301         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
6302                     (unsigned)NULL, (unsigned)NULL)) {
6303             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6304             return OMX_ErrorInsufficientResources;
6305         }
6306         m_in_alloc_cnt++;
6307     } else {
6308         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
6309         eRet = OMX_ErrorInsufficientResources;
6310     }
6311     return eRet;
6312 }
6313 
6314 /* ======================================================================
6315    FUNCTION
6316    omx_vdec::UseBuffer
6317 
6318    DESCRIPTION
6319    OMX Use Buffer method implementation.
6320 
6321    PARAMETERS
6322    <TBD>.
6323 
6324    RETURN VALUE
6325    OMX Error None , if everything successful.
6326 
6327    ========================================================================== */
use_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)6328 OMX_ERRORTYPE  omx_vdec::use_buffer(
6329         OMX_IN OMX_HANDLETYPE            hComp,
6330         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6331         OMX_IN OMX_U32                   port,
6332         OMX_IN OMX_PTR                   appData,
6333         OMX_IN OMX_U32                   bytes,
6334         OMX_IN OMX_U8*                   buffer)
6335 {
6336     OMX_ERRORTYPE error = OMX_ErrorNone;
6337 
6338     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
6339             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
6340             return OMX_ErrorBadParameter;
6341     }
6342     if (m_state == OMX_StateInvalid) {
6343         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
6344         return OMX_ErrorInvalidState;
6345     }
6346     if (port == OMX_CORE_INPUT_PORT_INDEX) {
6347         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
6348         // ensure that use-buffer was called for previous allocation.
6349         // Mix-and-match of useBuffer and allocateBuffer is not allowed
6350         if (m_inp_mem_ptr && !input_use_buffer) {
6351             DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
6352             return OMX_ErrorUndefined;
6353         }
6354         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
6355     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
6356         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
6357     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
6358         error = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
6359     } else {
6360         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
6361         error = OMX_ErrorBadPortIndex;
6362     }
6363     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
6364     if (error == OMX_ErrorNone) {
6365         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
6366             // Send the callback now
6367             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
6368             post_event(OMX_CommandStateSet,OMX_StateIdle,
6369                     OMX_COMPONENT_GENERATE_EVENT);
6370         }
6371         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
6372                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
6373             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
6374             post_event(OMX_CommandPortEnable,
6375                     OMX_CORE_INPUT_PORT_INDEX,
6376                     OMX_COMPONENT_GENERATE_EVENT);
6377         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
6378                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
6379             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
6380             post_event(OMX_CommandPortEnable,
6381                     OMX_CORE_OUTPUT_PORT_INDEX,
6382                     OMX_COMPONENT_GENERATE_EVENT);
6383         }
6384     }
6385     return error;
6386 }
6387 
free_input_buffer(unsigned int bufferindex,OMX_BUFFERHEADERTYPE * pmem_bufferHdr)6388 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
6389         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
6390 {
6391     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
6392         if (m_inp_heap_ptr[bufferindex].pBuffer)
6393             free(m_inp_heap_ptr[bufferindex].pBuffer);
6394         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
6395     }
6396     if (pmem_bufferHdr)
6397         free_input_buffer(pmem_bufferHdr);
6398     return OMX_ErrorNone;
6399 }
6400 
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)6401 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
6402 {
6403     unsigned int index = 0;
6404     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
6405         return OMX_ErrorBadParameter;
6406     }
6407     print_omx_buffer("free_input_buffer", bufferHdr);
6408 
6409     index = bufferHdr - m_inp_mem_ptr;
6410     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
6411 
6412     bufferHdr->pInputPortPrivate = NULL;
6413 
6414     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
6415         if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
6416             if (!secure_mode) {
6417                 ion_unmap(drv_ctx.ptr_inputbuffer[index].pmem_fd,
6418                           drv_ctx.ptr_inputbuffer[index].bufferaddr,
6419                           drv_ctx.ptr_inputbuffer[index].mmaped_size);
6420             }
6421 
6422             if (allocate_native_handle){
6423                 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
6424                 native_handle_close(nh);
6425                 native_handle_delete(nh);
6426             } else {
6427 #ifndef USE_ION
6428                 // Close fd for non-secure and secure non-native-handle case
6429                 close(drv_ctx.ptr_inputbuffer[index].pmem_fd);
6430 #endif
6431             }
6432             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
6433 
6434             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
6435                 free(m_desc_buffer_ptr[index].buf_addr);
6436                 m_desc_buffer_ptr[index].buf_addr = NULL;
6437                 m_desc_buffer_ptr[index].desc_data_size = 0;
6438             }
6439 #ifdef USE_ION
6440             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
6441 #endif
6442             m_in_alloc_cnt--;
6443         } else {
6444             DEBUG_PRINT_ERROR("Invalid input buffer fd %d", drv_ctx.ptr_inputbuffer[index].pmem_fd);
6445         }
6446     } else {
6447         DEBUG_PRINT_ERROR("Invalid input buffer index %d, drv_ctx.ptr_inputbuffer %p",
6448             index, drv_ctx.ptr_inputbuffer);
6449     }
6450 
6451     return OMX_ErrorNone;
6452 }
6453 
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr,bool intermediate)6454 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr,
6455                                            bool                 intermediate)
6456 {
6457     unsigned int index = 0;
6458 
6459     OMX_BUFFERHEADERTYPE  *omx_base_address =
6460              intermediate?m_intermediate_out_mem_ptr:m_out_mem_ptr;
6461     vdec_bufferpayload *omx_ptr_outputbuffer =
6462          intermediate?drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
6463     vdec_ion *omx_op_buf_ion_info =
6464         intermediate?drv_ctx.op_intermediate_buf_ion_info:drv_ctx.op_buf_ion_info;
6465 #ifdef USE_GBM
6466     vdec_gbm *omx_op_buf_gbm_info =
6467         intermediate?drv_ctx.op_intermediate_buf_gbm_info:drv_ctx.op_buf_gbm_info;
6468 #endif
6469     if (bufferHdr == NULL || omx_base_address == NULL) {
6470         return OMX_ErrorBadParameter;
6471     }
6472     print_omx_buffer("free_output_buffer", bufferHdr);
6473 
6474     index = bufferHdr - omx_base_address;
6475 
6476     if (index < drv_ctx.op_buf.actualcount
6477         && omx_ptr_outputbuffer) {
6478         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
6479                         omx_ptr_outputbuffer[index].bufferaddr);
6480 
6481         if (!dynamic_buf_mode) {
6482             if (streaming[CAPTURE_PORT] &&
6483                 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
6484                 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
6485                     DEBUG_PRINT_ERROR("STREAMOFF(CAPTURE_MPLANE) Failed");
6486                 } else {
6487                     DEBUG_PRINT_LOW("STREAMOFF(CAPTURE_MPLANE) Successful");
6488                 }
6489             }
6490 #ifdef _ANDROID_
6491             if (m_enable_android_native_buffers) {
6492                 if (!secure_mode) {
6493                     if (omx_ptr_outputbuffer[index].pmem_fd > 0) {
6494                         ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6495                                   omx_ptr_outputbuffer[index].bufferaddr,
6496                                   omx_ptr_outputbuffer[index].mmaped_size);
6497                     }
6498                 }
6499             } else {
6500 #endif
6501                 if (omx_ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
6502                     if (!secure_mode) {
6503                         ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6504                                   omx_ptr_outputbuffer[index].bufferaddr,
6505                                   omx_ptr_outputbuffer[index].mmaped_size);
6506                         omx_ptr_outputbuffer[index].bufferaddr = NULL;
6507                         omx_ptr_outputbuffer[index].mmaped_size = 0;
6508                     }
6509 #ifdef USE_GBM
6510                     free_gbm_memory(&omx_op_buf_gbm_info[index]);
6511 #elif defined USE_ION
6512                     free_ion_memory(&omx_op_buf_ion_info[index]);
6513 #endif
6514 
6515                     omx_ptr_outputbuffer[index].pmem_fd = -1;
6516                 }
6517 #ifdef _ANDROID_
6518             }
6519 #endif
6520         } //!dynamic_buf_mode
6521         if (intermediate == false) {
6522             OMX_BUFFERHEADERTYPE *tempBufHdr = m_intermediate_out_mem_ptr + index;
6523             if (client_buffers.is_color_conversion_enabled() &&
6524                 free_output_buffer(tempBufHdr, true) != OMX_ErrorNone) {
6525                 return OMX_ErrorBadParameter;
6526             }
6527 
6528             if (release_output_done()) {
6529             DEBUG_PRINT_HIGH("All output buffers released, free extradata");
6530             free_extradata();
6531             }
6532         }
6533     }
6534 
6535     return OMX_ErrorNone;
6536 }
6537 
allocate_input_heap_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)6538 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
6539         OMX_BUFFERHEADERTYPE **bufferHdr,
6540         OMX_U32              port,
6541         OMX_PTR              appData,
6542         OMX_U32              bytes)
6543 {
6544     OMX_BUFFERHEADERTYPE *input = NULL;
6545     unsigned char *buf_addr = NULL;
6546     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6547     unsigned   i = 0;
6548 
6549     /* Sanity Check*/
6550     if (bufferHdr == NULL) {
6551         return OMX_ErrorBadParameter;
6552     }
6553 
6554     if (m_inp_heap_ptr == NULL) {
6555         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
6556                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6557                          drv_ctx.ip_buf.actualcount);
6558         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
6559                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6560                           drv_ctx.ip_buf.actualcount);
6561 
6562         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
6563             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
6564             return OMX_ErrorInsufficientResources;
6565         }
6566     }
6567 
6568     /*Find a Free index*/
6569     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6570         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
6571             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6572             break;
6573         }
6574     }
6575 
6576     if (i < drv_ctx.ip_buf.actualcount) {
6577         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
6578 
6579         if (buf_addr == NULL) {
6580             return OMX_ErrorInsufficientResources;
6581         }
6582 
6583         *bufferHdr = (m_inp_heap_ptr + i);
6584         input = *bufferHdr;
6585         BITMASK_SET(&m_heap_inp_bm_count,i);
6586 
6587         input->pBuffer           = (OMX_U8 *)buf_addr;
6588         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
6589         input->nVersion.nVersion = OMX_SPEC_VERSION;
6590         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
6591         input->pAppPrivate       = appData;
6592         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
6593         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
6594         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
6595         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
6596         /*Add the Buffers to freeq*/
6597         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
6598                     (unsigned)NULL, (unsigned)NULL)) {
6599             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6600             return OMX_ErrorInsufficientResources;
6601         }
6602     } else {
6603         return OMX_ErrorBadParameter;
6604     }
6605 
6606     return eRet;
6607 }
6608 
6609 
6610 /* ======================================================================
6611    FUNCTION
6612    omx_vdec::AllocateInputBuffer
6613 
6614    DESCRIPTION
6615    Helper function for allocate buffer in the input pin
6616 
6617    PARAMETERS
6618    None.
6619 
6620    RETURN VALUE
6621    true/false
6622 
6623    ========================================================================== */
allocate_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)6624 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
6625         OMX_IN OMX_HANDLETYPE            hComp,
6626         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6627         OMX_IN OMX_U32                   port,
6628         OMX_IN OMX_PTR                   appData,
6629         OMX_IN OMX_U32                   bytes)
6630 {
6631     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6632     OMX_BUFFERHEADERTYPE *input = NULL;
6633     unsigned   i = 0;
6634     unsigned char *buf_addr = NULL;
6635     int pmem_fd = -1, ret = 0;
6636     unsigned int align_size = 0;
6637 
6638     (void) hComp;
6639     (void) port;
6640 
6641 
6642     if (bytes != drv_ctx.ip_buf.buffer_size) {
6643         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
6644                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
6645         return OMX_ErrorBadParameter;
6646     }
6647 
6648     if (!m_inp_mem_ptr) {
6649         /* Currently buffer reqs is being set only in set port defn                          */
6650         /* Client need not do set port definition if he sees enough buffers in get port defn */
6651         /* In such cases we need to do a set buffer reqs to driver. Doing it here            */
6652         struct v4l2_requestbuffers bufreq;
6653 
6654         DEBUG_PRINT_HIGH("Calling REQBUFS in %s ",__FUNCTION__);
6655         bufreq.memory = V4L2_MEMORY_USERPTR;
6656         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6657         bufreq.count = drv_ctx.ip_buf.actualcount;
6658         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
6659         if (ret) {
6660             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
6661             /*TODO: How to handle this case */
6662             eRet = OMX_ErrorInsufficientResources;
6663         } else if (bufreq.count != drv_ctx.ip_buf.actualcount) {
6664             DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d",
6665                 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count);
6666             eRet = OMX_ErrorInsufficientResources;
6667         }
6668 
6669         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
6670                 drv_ctx.ip_buf.actualcount,
6671                 (unsigned int)drv_ctx.ip_buf.buffer_size);
6672 
6673         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
6674                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
6675 
6676         if (m_inp_mem_ptr == NULL) {
6677             return OMX_ErrorInsufficientResources;
6678         }
6679 
6680         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
6681                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
6682 
6683         if (drv_ctx.ptr_inputbuffer == NULL) {
6684             return OMX_ErrorInsufficientResources;
6685         }
6686 #ifdef USE_ION
6687         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
6688                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
6689 
6690         if (drv_ctx.ip_buf_ion_info == NULL) {
6691             return OMX_ErrorInsufficientResources;
6692         }
6693 #endif
6694 
6695         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
6696             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
6697 #ifdef USE_ION
6698             drv_ctx.ip_buf_ion_info[i].data_fd = -1;
6699             drv_ctx.ip_buf_ion_info[i].dev_fd = -1;
6700 #endif
6701         }
6702     }
6703 
6704     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6705         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6706             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6707             break;
6708         }
6709     }
6710 
6711     if (i < drv_ctx.ip_buf.actualcount) {
6712         int rc;
6713         DEBUG_PRINT_LOW("Allocate input Buffer");
6714 #ifdef USE_ION
6715         align_size = drv_ctx.ip_buf.buffer_size + 512;
6716         align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
6717         // Input buffers are cached to make parsing faster
6718         bool status = alloc_map_ion_memory(
6719                 align_size, &drv_ctx.ip_buf_ion_info[i],
6720                 secure_mode ? SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
6721         if (status == false) {
6722             return OMX_ErrorInsufficientResources;
6723         }
6724         pmem_fd = drv_ctx.ip_buf_ion_info[i].data_fd;
6725 #endif
6726         if (!secure_mode) {
6727             buf_addr = (unsigned char *)ion_map(pmem_fd, drv_ctx.ip_buf.buffer_size);
6728             if (buf_addr == MAP_FAILED) {
6729 #ifdef USE_ION
6730                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
6731 #endif
6732                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
6733                 return OMX_ErrorInsufficientResources;
6734             }
6735         }
6736         *bufferHdr = (m_inp_mem_ptr + i);
6737         if (secure_mode)
6738             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
6739         else
6740             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
6741         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
6742         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
6743         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
6744         drv_ctx.ptr_inputbuffer [i].offset = 0;
6745 
6746         input = *bufferHdr;
6747         BITMASK_SET(&m_inp_bm_count,i);
6748         if (allocate_native_handle) {
6749             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
6750             if (!nh) {
6751                 DEBUG_PRINT_ERROR("Native handle create failed");
6752                 return OMX_ErrorInsufficientResources;
6753             }
6754             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
6755             input->pBuffer = (OMX_U8 *)nh;
6756         } else if (secure_mode || m_input_pass_buffer_fd) {
6757             /*Legacy method, pass ion fd stashed directly in pBuffer*/
6758             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
6759         } else {
6760             input->pBuffer           = (OMX_U8 *)buf_addr;
6761         }
6762         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
6763         input->nVersion.nVersion = OMX_SPEC_VERSION;
6764         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
6765         input->pAppPrivate       = appData;
6766         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
6767         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
6768 
6769         if (drv_ctx.disable_dmx) {
6770             eRet = allocate_desc_buffer(i);
6771         }
6772     } else {
6773         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
6774         eRet = OMX_ErrorInsufficientResources;
6775     }
6776 
6777     if (eRet == OMX_ErrorNone)
6778         DEBUG_PRINT_HIGH("Allocate_input_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d",
6779             i, input, input->pBuffer, input->nAllocLen,
6780             input->nOffset, drv_ctx.ptr_inputbuffer[i].pmem_fd);
6781 
6782     return eRet;
6783 }
6784 
6785 
6786 /* ======================================================================
6787    FUNCTION
6788    omx_vdec::AllocateOutputBuffer
6789 
6790    DESCRIPTION
6791    Helper fn for AllocateBuffer in the output pin
6792 
6793    PARAMETERS
6794    <TBD>.
6795 
6796    RETURN VALUE
6797    OMX Error None if everything went well.
6798 
6799    ========================================================================== */
allocate_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN bool intermediate,OMX_IN int index)6800 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
6801         OMX_IN OMX_HANDLETYPE            hComp,
6802         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6803         OMX_IN OMX_U32                   port,
6804         OMX_IN OMX_PTR                   appData,
6805         OMX_IN OMX_U32                   bytes,
6806         OMX_IN bool                      intermediate,
6807         OMX_IN int                       index)
6808 {
6809     (void)hComp;
6810     (void)port;
6811 
6812     OMX_ERRORTYPE eRet = OMX_ErrorNone;
6813     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
6814     unsigned                         i= 0; // Temporary counter
6815 #ifdef USE_ION
6816     struct ion_allocation_data ion_alloc_data;
6817 #endif
6818     OMX_BUFFERHEADERTYPE  **omx_base_address =
6819         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
6820 
6821     vdec_bufferpayload **omx_ptr_outputbuffer =
6822         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
6823     vdec_output_frameinfo **omx_ptr_respbuffer =
6824         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
6825     vdec_ion **omx_op_buf_ion_info =
6826         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
6827 #ifdef USE_GBM
6828     vdec_gbm **omx_op_buf_gbm_info =
6829         intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
6830 #endif
6831 
6832     if (!*omx_base_address) {
6833         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
6834                 drv_ctx.op_buf.actualcount,
6835                 (unsigned int)drv_ctx.op_buf.buffer_size);
6836         int nBufHdrSize        = 0;
6837         int nPlatformEntrySize = 0;
6838         int nPlatformListSize  = 0;
6839         int nPMEMInfoSize = 0;
6840 
6841         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
6842         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
6843         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
6844 
6845         nBufHdrSize        = drv_ctx.op_buf.actualcount *
6846             sizeof(OMX_BUFFERHEADERTYPE);
6847         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
6848             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
6849         nPlatformListSize  = drv_ctx.op_buf.actualcount *
6850             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
6851         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
6852             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
6853 
6854         *omx_base_address = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
6855         // Alloc mem for platform specific info
6856         char *pPtr=NULL;
6857         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
6858                 nPMEMInfoSize,1);
6859         *omx_ptr_outputbuffer = (struct vdec_bufferpayload *)    \
6860                        calloc (sizeof(struct vdec_bufferpayload),
6861                                drv_ctx.op_buf.actualcount);
6862         *omx_ptr_respbuffer = (struct vdec_output_frameinfo  *)\
6863                      calloc (sizeof (struct vdec_output_frameinfo),
6864                              drv_ctx.op_buf.actualcount);
6865         if (!*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
6866             DEBUG_PRINT_ERROR("Failed to alloc outputbuffer or respbuffer ");
6867             free(pPtr);
6868             return OMX_ErrorInsufficientResources;
6869         }
6870 
6871 #ifdef USE_GBM
6872         *omx_op_buf_gbm_info = (struct vdec_gbm *)\
6873                       calloc (sizeof(struct vdec_gbm),
6874                       drv_ctx.op_buf.actualcount);
6875         if (!*omx_op_buf_gbm_info) {
6876                  DEBUG_PRINT_ERROR("Failed to alloc op_buf_gbm_info");
6877             return OMX_ErrorInsufficientResources;
6878         }
6879         drv_ctx.gbm_device_fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
6880         if (drv_ctx.gbm_device_fd < 0) {
6881            DEBUG_PRINT_ERROR("opening dri device for gbm failed with fd = %d", drv_ctx.gbm_device_fd);
6882            return OMX_ErrorInsufficientResources;
6883         }
6884 #elif defined USE_ION
6885         *omx_op_buf_ion_info = (struct vdec_ion *)\
6886                       calloc (sizeof(struct vdec_ion),
6887                               drv_ctx.op_buf.actualcount);
6888         if (!*omx_op_buf_ion_info) {
6889             DEBUG_PRINT_ERROR("Failed to alloc op_buf_ion_info");
6890             return OMX_ErrorInsufficientResources;
6891         }
6892 #endif
6893 
6894         if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
6895             && *omx_ptr_respbuffer) {
6896             bufHdr          =  *omx_base_address;
6897             if (m_platform_list) {
6898                 free(m_platform_list);
6899             }
6900             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
6901             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
6902                 (((char *) m_platform_list)  + nPlatformListSize);
6903             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6904                 (((char *) m_platform_entry) + nPlatformEntrySize);
6905             pPlatformList   = m_platform_list;
6906             pPlatformEntry  = m_platform_entry;
6907             pPMEMInfo       = m_pmem_info;
6908 
6909             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
6910 
6911             // Settting the entire storage nicely
6912             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
6913                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
6914                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
6915                 // Set the values when we determine the right HxW param
6916                 bufHdr->nAllocLen          = bytes;
6917                 bufHdr->nFilledLen         = 0;
6918                 bufHdr->pAppPrivate        = appData;
6919                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
6920                 // Platform specific PMEM Information
6921                 // Initialize the Platform Entry
6922                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
6923                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6924                 pPlatformEntry->entry      = pPMEMInfo;
6925                 // Initialize the Platform List
6926                 pPlatformList->nEntries    = 1;
6927                 pPlatformList->entryList   = pPlatformEntry;
6928                 // Keep pBuffer NULL till vdec is opened
6929                 bufHdr->pBuffer            = NULL;
6930                 bufHdr->nOffset            = 0;
6931                 pPMEMInfo->offset = 0;
6932                 pPMEMInfo->pmem_fd = -1;
6933                 bufHdr->pPlatformPrivate = pPlatformList;
6934                 /*Create a mapping between buffers*/
6935                 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
6936                 (*omx_ptr_respbuffer)[i].client_data = (void *) \
6937                     &(*omx_ptr_outputbuffer)[i];
6938                 // Move the buffer and buffer header pointers
6939                 bufHdr++;
6940                 pPMEMInfo++;
6941                 pPlatformEntry++;
6942                 pPlatformList++;
6943             }
6944         } else {
6945             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
6946                               *omx_base_address, pPtr);
6947             if (*omx_base_address) {
6948                 free(*omx_base_address);
6949                 *omx_base_address = NULL;
6950             }
6951             if (pPtr) {
6952                 free(pPtr);
6953                 pPtr = NULL;
6954             }
6955             if (*omx_ptr_outputbuffer) {
6956                 free(*omx_ptr_outputbuffer);
6957                 *omx_ptr_outputbuffer = NULL;
6958             }
6959             if (*omx_ptr_respbuffer) {
6960                 free(*omx_ptr_respbuffer);
6961                 *omx_ptr_respbuffer = NULL;
6962             }
6963 #ifdef USE_GBM
6964       if(drv_ctx.gbm_device_fd >= 0) {
6965        DEBUG_PRINT_LOW("Close gbm device");
6966        close(drv_ctx.gbm_device_fd);
6967        drv_ctx.gbm_device_fd = -1;
6968     }
6969             if (*omx_op_buf_gbm_info) {
6970                 DEBUG_PRINT_LOW("Free o/p gbm context");
6971                 free(*omx_op_buf_gbm_info);
6972                 *omx_op_buf_gbm_info = NULL;
6973             }
6974 #elif defined USE_ION
6975             if (*omx_op_buf_ion_info) {
6976                 DEBUG_PRINT_LOW("Free o/p ion context");
6977                 free(*omx_op_buf_ion_info);
6978                 *omx_op_buf_ion_info = NULL;
6979             }
6980 #endif
6981             eRet =  OMX_ErrorInsufficientResources;
6982         }
6983         if (eRet == OMX_ErrorNone)
6984             eRet = allocate_extradata();
6985     }
6986 
6987     if (intermediate == true && index != -1) {
6988         i = index;
6989     } else {
6990         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
6991             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
6992                 break;
6993             }
6994         }
6995     }
6996 
6997     if (eRet == OMX_ErrorNone) {
6998         if (i < drv_ctx.op_buf.actualcount) {
6999             int rc;
7000             int pmem_fd = -1;
7001             int fd = -1;
7002             unsigned char *pmem_baseaddress = NULL;
7003 #ifdef USE_GBM
7004             int pmeta_fd = -1;
7005             // Allocate output buffers as cached to improve performance of software-reading
7006             // of the YUVs. Output buffers are cache-invalidated in driver.
7007             // If color-conversion is involved, Only the C2D output buffers are cached, no
7008             // need to cache the decoder's output buffers
7009             int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
7010             bool status = alloc_map_gbm_memory(
7011                                drv_ctx.video_resolution.frame_width,
7012                                drv_ctx.video_resolution.frame_height,
7013                                drv_ctx.gbm_device_fd,
7014                                &(*omx_op_buf_gbm_info)[i],
7015                                (secure_mode && !secure_scaling_to_non_secure_opb) ?
7016                                       SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
7017             if (status == false) {
7018                 return OMX_ErrorInsufficientResources;
7019             }
7020             pmem_fd = (*omx_op_buf_gbm_info)[i].bo_fd;
7021             pmeta_fd = (*omx_op_buf_gbm_info)[i].meta_fd;
7022 #elif defined USE_ION
7023             // Allocate output buffers as cached to improve performance of software-reading
7024             // of the YUVs. Output buffers are cache-invalidated in driver.
7025             // If color-conversion is involved, Only the C2D output buffers are cached, no
7026             // need to cache the decoder's output buffers
7027             int cache_flag = ION_FLAG_CACHED;
7028             if (intermediate == true && client_buffers.is_color_conversion_enabled()) {
7029                 cache_flag = 0;
7030             }
7031             bool status = alloc_map_ion_memory(drv_ctx.op_buf.buffer_size,
7032                                                &(*omx_op_buf_ion_info)[i],
7033                     (secure_mode && !secure_scaling_to_non_secure_opb) ?
7034                     SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
7035             if (status == false) {
7036                 return OMX_ErrorInsufficientResources;
7037             }
7038             pmem_fd = (*omx_op_buf_ion_info)[i].data_fd;
7039 #endif
7040             if (!secure_mode) {
7041                 pmem_baseaddress = (unsigned char *)ion_map(pmem_fd, drv_ctx.op_buf.buffer_size);
7042                 if (pmem_baseaddress == MAP_FAILED) {
7043                     DEBUG_PRINT_ERROR("MMAP failed for Size %u",
7044                             (unsigned int)drv_ctx.op_buf.buffer_size);
7045 #ifdef USE_GBM
7046                     free_gbm_memory(&(*omx_op_buf_gbm_info)[i]);
7047 #elif defined USE_ION
7048                     free_ion_memory(&(*omx_op_buf_ion_info)[i]);
7049 #endif
7050                     return OMX_ErrorInsufficientResources;
7051                 }
7052             }
7053             (*omx_ptr_outputbuffer)[i].pmem_fd = pmem_fd;
7054 #ifdef USE_GBM
7055             m_pmem_info[i].pmeta_fd = pmeta_fd;
7056 #endif
7057             (*omx_ptr_outputbuffer)[i].offset = 0;
7058             (*omx_ptr_outputbuffer)[i].bufferaddr = pmem_baseaddress;
7059             (*omx_ptr_outputbuffer)[i].mmaped_size = drv_ctx.op_buf.buffer_size;
7060             (*omx_ptr_outputbuffer)[i].buffer_len = drv_ctx.op_buf.buffer_size;
7061             m_pmem_info[i].pmem_fd = pmem_fd;
7062             m_pmem_info[i].size = (*omx_ptr_outputbuffer)[i].buffer_len;
7063             m_pmem_info[i].mapped_size = (*omx_ptr_outputbuffer)[i].mmaped_size;
7064             m_pmem_info[i].buffer = (*omx_ptr_outputbuffer)[i].bufferaddr;
7065             m_pmem_info[i].offset = (*omx_ptr_outputbuffer)[i].offset;
7066 
7067             *bufferHdr = (*omx_base_address + i );
7068             if (secure_mode) {
7069 #ifdef USE_GBM
7070                 (*omx_ptr_outputbuffer)[i].bufferaddr =
7071                     (OMX_U8 *)(intptr_t)(*omx_op_buf_gbm_info)[i].bo_fd;
7072 #elif defined USE_ION
7073                 (*omx_ptr_outputbuffer)[i].bufferaddr =
7074                     (OMX_U8 *)(intptr_t)(*omx_op_buf_ion_info)[i].data_fd;
7075 #endif
7076             }
7077             if (intermediate == false &&
7078                 client_buffers.is_color_conversion_enabled()) {
7079                 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
7080                 eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
7081                                               port, appData,
7082                                               drv_ctx.op_buf.buffer_size,
7083                                               true, i);
7084             }
7085             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
7086                 enum v4l2_buf_type buf_type;
7087 
7088                 set_buffer_req(&drv_ctx.op_buf);
7089                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7090                 if (!client_buffers.is_color_conversion_enabled() ||
7091                     (client_buffers.is_color_conversion_enabled() && intermediate == true)) {
7092                     rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7093                     if (rc) {
7094                         DEBUG_PRINT_ERROR("STREAMON(CAPTURE_MPLANE) Failed");
7095                         return OMX_ErrorInsufficientResources;
7096                     } else {
7097                         streaming[CAPTURE_PORT] = true;
7098                         DEBUG_PRINT_LOW("STREAMON(CAPTURE_MPLANE) Successful");
7099                     }
7100                 }
7101             }
7102 
7103             (*bufferHdr)->pBuffer = (OMX_U8*)(*omx_ptr_outputbuffer)[i].bufferaddr;
7104             (*bufferHdr)->pAppPrivate = appData;
7105             BITMASK_SET(&m_out_bm_count,i);
7106         } else {
7107             DEBUG_PRINT_ERROR("Faile to allocate output buffer (%d) maxcount %d",
7108                 i, drv_ctx.op_buf.actualcount);
7109             eRet = OMX_ErrorInsufficientResources;
7110         }
7111     }
7112 
7113     if (eRet == OMX_ErrorNone)
7114         DEBUG_PRINT_HIGH("Allocate_output_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d intermediate %d",
7115                          i, (*bufferHdr), (*bufferHdr)->pBuffer, (*bufferHdr)->nAllocLen,
7116                          (*bufferHdr)->nOffset, (*omx_ptr_outputbuffer)[i].pmem_fd,
7117                          intermediate);
7118     return eRet;
7119 }
7120 
7121 
7122 // AllocateBuffer  -- API Call
7123 /* ======================================================================
7124    FUNCTION
7125    omx_vdec::AllocateBuffer
7126 
7127    DESCRIPTION
7128    Returns zero if all the buffers released..
7129 
7130    PARAMETERS
7131    None.
7132 
7133    RETURN VALUE
7134    true/false
7135 
7136    ========================================================================== */
allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)7137 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
7138         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
7139         OMX_IN OMX_U32                        port,
7140         OMX_IN OMX_PTR                     appData,
7141         OMX_IN OMX_U32                       bytes)
7142 {
7143     unsigned i = 0;
7144     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
7145 
7146     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
7147     if (m_state == OMX_StateInvalid) {
7148         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
7149         return OMX_ErrorInvalidState;
7150     }
7151 
7152     if (port == OMX_CORE_INPUT_PORT_INDEX) {
7153         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
7154         // ensure that use-buffer was never called.
7155         // Mix-and-match of useBuffer and allocateBuffer is not allowed
7156         if (m_inp_mem_ptr && input_use_buffer) {
7157             DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
7158             return OMX_ErrorUndefined;
7159         }
7160         if (arbitrary_bytes) {
7161             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
7162         } else {
7163             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
7164         }
7165     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7166         if (output_use_buffer) {
7167             DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
7168             return OMX_ErrorBadParameter;
7169         }
7170         eRet = allocate_output_buffer(hComp, bufferHdr, port, appData, bytes);
7171     } else {
7172         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
7173         eRet = OMX_ErrorBadPortIndex;
7174     }
7175     if (eRet == OMX_ErrorNone) {
7176         if (allocate_done()) {
7177             DEBUG_PRINT_HIGH("Allocated all buffers on port %d", port);
7178             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
7179                 // Send the callback now
7180                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
7181                 post_event(OMX_CommandStateSet,OMX_StateIdle,
7182                         OMX_COMPONENT_GENERATE_EVENT);
7183             }
7184         }
7185         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
7186             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
7187                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
7188                 post_event(OMX_CommandPortEnable,
7189                         OMX_CORE_INPUT_PORT_INDEX,
7190                         OMX_COMPONENT_GENERATE_EVENT);
7191             }
7192         }
7193         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
7194             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
7195                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
7196                 post_event(OMX_CommandPortEnable,
7197                         OMX_CORE_OUTPUT_PORT_INDEX,
7198                         OMX_COMPONENT_GENERATE_EVENT);
7199             }
7200         }
7201     }
7202     return eRet;
7203 }
7204 
7205 // Free Buffer - API call
7206 /* ======================================================================
7207    FUNCTION
7208    omx_vdec::FreeBuffer
7209 
7210    DESCRIPTION
7211 
7212    PARAMETERS
7213    None.
7214 
7215    RETURN VALUE
7216    true/false
7217 
7218    ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7219 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
7220         OMX_IN OMX_U32                 port,
7221         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7222 {
7223     OMX_ERRORTYPE eRet = OMX_ErrorNone;
7224     unsigned int nPortIndex;
7225     (void) hComp;
7226 
7227     auto_lock l(buf_lock);
7228     if (m_state == OMX_StateIdle &&
7229             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7230         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
7231     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
7232             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
7233         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
7234     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
7235                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
7236             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
7237              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
7238         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
7239     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
7240         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
7241         post_event(OMX_EventError,
7242                 OMX_ErrorPortUnpopulated,
7243                 OMX_COMPONENT_GENERATE_EVENT);
7244         m_buffer_error = true;
7245         return OMX_ErrorIncorrectStateOperation;
7246     } else if (m_state != OMX_StateInvalid) {
7247         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
7248         post_event(OMX_EventError,
7249                 OMX_ErrorPortUnpopulated,
7250                 OMX_COMPONENT_GENERATE_EVENT);
7251     }
7252 
7253     if (port == OMX_CORE_INPUT_PORT_INDEX) {
7254         /*Check if arbitrary bytes*/
7255         if (!arbitrary_bytes && !input_use_buffer)
7256             nPortIndex = buffer - m_inp_mem_ptr;
7257         else
7258             nPortIndex = buffer - m_inp_heap_ptr;
7259 
7260         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
7261         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
7262                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
7263             // Clear the bit associated with it.
7264             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
7265             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
7266             if (input_use_buffer == true) {
7267 
7268                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
7269                 if (m_phdr_pmem_ptr)
7270                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
7271             } else {
7272                 if (arbitrary_bytes) {
7273                     if (m_phdr_pmem_ptr)
7274                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
7275                     else
7276                         free_input_buffer(nPortIndex,NULL);
7277                 } else
7278                     free_input_buffer(buffer);
7279             }
7280             m_inp_bPopulated = OMX_FALSE;
7281             /*Free the Buffer Header*/
7282             if (release_input_done()) {
7283                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
7284                 free_input_buffer_header();
7285             }
7286         } else {
7287             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
7288             eRet = OMX_ErrorBadPortIndex;
7289         }
7290 
7291         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
7292                 && release_input_done()) {
7293             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7294             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
7295             post_event(OMX_CommandPortDisable,
7296                     OMX_CORE_INPUT_PORT_INDEX,
7297                     OMX_COMPONENT_GENERATE_EVENT);
7298         }
7299     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7300         // check if the buffer is valid
7301         OMX_BUFFERHEADERTYPE  *omx_base_address =
7302             client_buffers.is_color_conversion_enabled()?
7303             m_intermediate_out_mem_ptr:m_out_mem_ptr;
7304         nPortIndex = buffer - m_out_mem_ptr;
7305         if (nPortIndex < drv_ctx.op_buf.actualcount &&
7306                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
7307             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
7308             // Clear the bit associated with it.
7309             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
7310             m_out_bPopulated = OMX_FALSE;
7311             free_output_buffer (buffer);
7312 
7313             if (release_output_done()) {
7314                 DEBUG_PRINT_HIGH("All output buffers released.");
7315                 free_output_buffer_header();
7316             }
7317         } else {
7318             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
7319             eRet = OMX_ErrorBadPortIndex;
7320         }
7321         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
7322                 && release_output_done()) {
7323             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7324             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
7325 #ifdef _ANDROID_ICS_
7326             if (m_enable_android_native_buffers) {
7327                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
7328                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
7329             }
7330 #endif
7331 
7332             post_event(OMX_CommandPortDisable,
7333                     OMX_CORE_OUTPUT_PORT_INDEX,
7334                     OMX_COMPONENT_GENERATE_EVENT);
7335         }
7336     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
7337         nPortIndex = buffer - m_client_output_extradata_mem_ptr;
7338         DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
7339 
7340         BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
7341 
7342         if (release_output_extradata_done()) {
7343             free_output_extradata_buffer_header();
7344         }
7345     } else {
7346         eRet = OMX_ErrorBadPortIndex;
7347     }
7348     if ((eRet == OMX_ErrorNone) &&
7349             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7350         if (release_done()) {
7351             /*
7352              * Reset buffer requirements here to ensure setting buffer requirement
7353              * when component move to executing state from loaded state via idle.
7354              */
7355             drv_ctx.op_buf.buffer_size = 0;
7356             drv_ctx.op_buf.actualcount = 0;
7357 
7358             // Send the callback now
7359             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
7360             post_event(OMX_CommandStateSet, OMX_StateLoaded,
7361                     OMX_COMPONENT_GENERATE_EVENT);
7362             m_buffer_error = false;
7363         }
7364     }
7365     return eRet;
7366 }
7367 
7368 
7369 /* ======================================================================
7370    FUNCTION
7371    omx_vdec::EmptyThisBuffer
7372 
7373    DESCRIPTION
7374    This routine is used to push the encoded video frames to
7375    the video decoder.
7376 
7377    PARAMETERS
7378    None.
7379 
7380    RETURN VALUE
7381    OMX Error None if everything went successful.
7382 
7383    ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7384 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
7385         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7386 {
7387     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
7388     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
7389 
7390     if (m_state != OMX_StateExecuting &&
7391             m_state != OMX_StatePause &&
7392             m_state != OMX_StateIdle) {
7393         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
7394         return OMX_ErrorInvalidState;
7395     }
7396 
7397     if (m_error_propogated) {
7398         DEBUG_PRINT_ERROR("Empty this buffer not allowed after error");
7399         return OMX_ErrorHardware;
7400     }
7401 
7402     if (buffer == NULL) {
7403         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
7404         return OMX_ErrorBadParameter;
7405     }
7406     print_omx_buffer("EmptyThisBuffer", buffer);
7407 
7408     if (!m_inp_bEnabled) {
7409         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
7410         return OMX_ErrorIncorrectStateOperation;
7411     }
7412 
7413     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
7414         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
7415         return OMX_ErrorBadPortIndex;
7416     }
7417 
7418     if (perf_flag) {
7419         if (!latency) {
7420             dec_time.stop();
7421             latency = dec_time.processing_time_us();
7422             dec_time.start();
7423         }
7424     }
7425 
7426     if (arbitrary_bytes) {
7427         nBufferIndex = buffer - m_inp_heap_ptr;
7428     } else {
7429         if (input_use_buffer == true) {
7430             nBufferIndex = buffer - m_inp_heap_ptr;
7431             if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7432                 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
7433                 return OMX_ErrorBadParameter;
7434             }
7435             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
7436             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
7437             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
7438             buffer = &m_inp_mem_ptr[nBufferIndex];
7439             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
7440                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
7441         } else {
7442             nBufferIndex = buffer - m_inp_mem_ptr;
7443         }
7444     }
7445 
7446     if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7447         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
7448         return OMX_ErrorBadParameter;
7449     }
7450 
7451     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7452         codec_config_flag = true;
7453         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
7454     }
7455 
7456     /* The client should not set this when codec is in arbitrary bytes mode */
7457     if (m_input_pass_buffer_fd) {
7458         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
7459     }
7460 
7461     /* Check if the input timestamp in seconds is greater than LONG_MAX
7462        or lesser than LONG_MIN. */
7463     if (buffer->nTimeStamp / 1000000 > LONG_MAX ||
7464        buffer->nTimeStamp / 1000000 < LONG_MIN) {
7465         /* This timestamp cannot be contained in driver timestamp field */
7466         DEBUG_PRINT_ERROR("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u) >> Invalid timestamp",
7467             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
7468         return OMX_ErrorBadParameter;
7469     }
7470 
7471     m_etb_count++;
7472     //To handle wrap around case. m_etb_count++ to ensure value is non-zero.
7473     if (!m_etb_count)
7474         m_etb_count++;
7475     m_etb_timestamp = buffer->nTimeStamp;
7476     DEBUG_PRINT_LOW("[ETB] nCnt(%u) BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
7477             m_etb_count, buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
7478     buffer->pMarkData = (OMX_PTR)(unsigned long)m_etb_count;
7479     if (arbitrary_bytes) {
7480         post_event ((unsigned long)hComp,(unsigned long)buffer,
7481                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
7482     } else {
7483         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
7484     }
7485 
7486     time_stamp_dts.insert_timestamp(buffer);
7487     return OMX_ErrorNone;
7488 }
7489 
7490 /* ======================================================================
7491    FUNCTION
7492    omx_vdec::empty_this_buffer_proxy
7493 
7494    DESCRIPTION
7495    This routine is used to push the encoded video frames to
7496    the video decoder.
7497 
7498    PARAMETERS
7499    None.
7500 
7501    RETURN VALUE
7502    OMX Error None if everything went successful.
7503 
7504    ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7505 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
7506         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7507 {
7508     VIDC_TRACE_NAME_HIGH("ETB");
7509     (void) hComp;
7510     int push_cnt = 0,i=0;
7511     unsigned nPortIndex = 0;
7512     OMX_ERRORTYPE ret = OMX_ErrorNone;
7513     struct vdec_bufferpayload *temp_buffer;
7514     bool port_setting_changed = true;
7515 
7516     /*Should we generate a Aync error event*/
7517     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
7518         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
7519         return OMX_ErrorBadParameter;
7520     }
7521 
7522     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
7523 
7524     if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
7525         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
7526                 nPortIndex);
7527         return OMX_ErrorBadParameter;
7528     }
7529 
7530     pending_input_buffers++;
7531     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
7532 
7533     /* return zero length and not an EOS buffer */
7534     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
7535             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
7536         DEBUG_PRINT_HIGH("return zero length buffer");
7537         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7538                 OMX_COMPONENT_GENERATE_EBD);
7539         return OMX_ErrorNone;
7540     }
7541 
7542     if (input_flush_progress == true) {
7543         DEBUG_PRINT_LOW("Flush in progress return buffer ");
7544         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7545                 OMX_COMPONENT_GENERATE_EBD);
7546         return OMX_ErrorNone;
7547     }
7548 
7549     if (m_error_propogated == true) {
7550         DEBUG_PRINT_LOW("Return buffer in error state");
7551         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7552                 OMX_COMPONENT_GENERATE_EBD);
7553         return OMX_ErrorNone;
7554     }
7555 
7556     auto_lock l(buf_lock);
7557     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
7558 
7559     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
7560         return OMX_ErrorBadParameter;
7561     }
7562 
7563     if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
7564         DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
7565         return OMX_ErrorBadParameter;
7566     }
7567 
7568     VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000);
7569     VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen);
7570     /*for use buffer we need to memcpy the data*/
7571     temp_buffer->buffer_len = buffer->nFilledLen;
7572 
7573     if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
7574         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
7575             if (arbitrary_bytes) {
7576                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
7577             } else {
7578                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
7579                         buffer->nFilledLen);
7580             }
7581         } else {
7582             return OMX_ErrorBadParameter;
7583         }
7584 
7585     }
7586 
7587     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
7588         DEBUG_PRINT_LOW("ETB: dmx enabled");
7589         if (m_demux_entries == 0) {
7590             extract_demux_addr_offsets(buffer);
7591         }
7592 
7593         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
7594         handle_demux_data(buffer);
7595     }
7596 
7597     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len, buffer->nTimeStamp, temp_buffer->pmem_fd);
7598 
7599     if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
7600         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7601     }
7602 
7603     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7604         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
7605         h264_scratch.nFilledLen = 0;
7606         nal_count = 0;
7607         look_ahead_nal = false;
7608         frame_count = 0;
7609         if (m_frame_parser.mutils)
7610             m_frame_parser.mutils->initialize_frame_checking_environment();
7611         m_frame_parser.flush();
7612         h264_last_au_ts = LLONG_MAX;
7613         h264_last_au_flags = 0;
7614         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
7615         m_demux_entries = 0;
7616     }
7617     struct v4l2_buffer buf;
7618     struct v4l2_plane plane;
7619     memset( (void *)&buf, 0, sizeof(buf));
7620     memset( (void *)&plane, 0, sizeof(plane));
7621     int rc;
7622     unsigned long  print_count;
7623     if (temp_buffer->buffer_len == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7624         struct v4l2_decoder_cmd dec;
7625 
7626         if (!streaming[OUTPUT_PORT]) {
7627             enum v4l2_buf_type buf_type;
7628             int ret = 0;
7629 
7630             buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7631             DEBUG_PRINT_HIGH("Calling streamon before issuing stop command for EOS");
7632             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7633             if (!ret) {
7634                 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7635                 streaming[OUTPUT_PORT] = true;
7636             } else {
7637                 DEBUG_PRINT_ERROR("Streamon failed before sending stop command");
7638                 return OMX_ErrorHardware;
7639             }
7640         }
7641 
7642         DEBUG_PRINT_HIGH("Input EOS reached. Converted to STOP command") ;
7643         memset(&dec, 0, sizeof(dec));
7644         dec.cmd = V4L2_DEC_CMD_STOP;
7645         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec);
7646         post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7647             OMX_COMPONENT_GENERATE_EBD);
7648         if (rc < 0) {
7649             DEBUG_PRINT_ERROR("Decoder CMD failed");
7650             return OMX_ErrorHardware;
7651         }
7652         return OMX_ErrorNone;
7653     }
7654 
7655     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
7656         DEBUG_PRINT_HIGH("Input EOS reached") ;
7657         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
7658     }
7659 
7660     // update hdr10plusinfo list with cookie as pMarkData
7661     update_hdr10plusinfo_cookie_using_timestamp(buffer->pMarkData, buffer->nTimeStamp);
7662 
7663     OMX_ERRORTYPE eRet = OMX_ErrorNone;
7664     buf.index = nPortIndex;
7665     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7666     buf.memory = V4L2_MEMORY_USERPTR;
7667     plane.bytesused = temp_buffer->buffer_len;
7668     plane.length = drv_ctx.ip_buf.buffer_size;
7669     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
7670         (unsigned long)temp_buffer->offset;
7671     plane.reserved[0] = temp_buffer->pmem_fd;
7672     plane.reserved[1] = temp_buffer->offset;
7673     plane.reserved[3] = (unsigned long)buffer->pMarkData;
7674     plane.reserved[4] = (unsigned long)buffer->hMarkTargetComponent;
7675     plane.data_offset = 0;
7676     buf.m.planes = &plane;
7677     buf.length = 1;
7678     //assumption is that timestamp is in milliseconds
7679     buf.timestamp.tv_sec = buffer->nTimeStamp / 1000000;
7680     buf.timestamp.tv_usec = (buffer->nTimeStamp % 1000000);
7681     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
7682 #if NEED_TO_REVISIT
7683     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
7684 #endif
7685 
7686     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7687         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
7688         android_atomic_inc(&m_queued_codec_config_count);
7689     }
7690 
7691     print_v4l2_buffer("QBUF-ETB", &buf);
7692     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7693     if (rc) {
7694         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
7695         print_v4l2_buffer("QBUF failed", &buf);
7696         print_omx_buffer("EBD on qbuf failed", buffer);
7697         m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
7698         return OMX_ErrorHardware;
7699     }
7700 
7701     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7702         codec_config_flag = false;
7703     }
7704     if (!streaming[OUTPUT_PORT]) {
7705         enum v4l2_buf_type buf_type;
7706         int ret,r;
7707 
7708         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7709         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
7710         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7711         if (!ret) {
7712             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7713             streaming[OUTPUT_PORT] = true;
7714         } else if (errno == EBUSY) {
7715             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
7716             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7717                     OMX_COMPONENT_GENERATE_EBD);
7718             return OMX_ErrorInsufficientResources;
7719         } else {
7720             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
7721             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
7722             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7723                     OMX_COMPONENT_GENERATE_EBD);
7724             return OMX_ErrorBadParameter;
7725         }
7726     }
7727 
7728     return ret;
7729 }
7730 
7731 /* ======================================================================
7732    FUNCTION
7733    omx_vdec::FillThisBuffer
7734 
7735    DESCRIPTION
7736    IL client uses this method to release the frame buffer
7737    after displaying them.
7738 
7739    PARAMETERS
7740    None.
7741 
7742    RETURN VALUE
7743    true/false
7744 
7745    ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7746 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
7747         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7748 {
7749     if (m_state != OMX_StateExecuting &&
7750             m_state != OMX_StatePause &&
7751             m_state != OMX_StateIdle) {
7752         DEBUG_PRINT_ERROR("FTB in Invalid State");
7753         return OMX_ErrorInvalidState;
7754     }
7755 
7756     if (buffer == NULL || buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
7757         DEBUG_PRINT_ERROR("ERROR:FTB invalid buffer %p or PortIndex - %d",
7758              buffer, buffer ? (int)buffer->nOutputPortIndex : -1);
7759         return OMX_ErrorBadPortIndex;
7760     }
7761     print_omx_buffer("FillThisBuffer", buffer);
7762 
7763     if (m_error_propogated) {
7764         DEBUG_PRINT_ERROR("Fill this buffer not allowed after error");
7765         return OMX_ErrorHardware;
7766     }
7767 
7768     if (!m_out_bEnabled) {
7769         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
7770         return OMX_ErrorIncorrectStateOperation;
7771     }
7772 
7773     unsigned nPortIndex = buffer - m_out_mem_ptr;
7774     if (dynamic_buf_mode) {
7775         private_handle_t *handle = NULL;
7776         struct VideoDecoderOutputMetaData *meta = NULL;
7777 
7778         if (!buffer || !buffer->pBuffer) {
7779             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
7780             return OMX_ErrorBadParameter;
7781         }
7782 
7783         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
7784         handle = (private_handle_t *)meta->pHandle;
7785 
7786         //get the buffer type and fd info
7787         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ",
7788                         meta, meta->eType, meta->pHandle);
7789 
7790         if (!handle) {
7791             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
7792             return OMX_ErrorBadParameter;
7793         }
7794 
7795         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
7796         if (nPortIndex < drv_ctx.op_buf.actualcount &&
7797             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
7798             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
7799             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
7800 
7801             //Store private handle from GraphicBuffer
7802             native_buffer[nPortIndex].privatehandle = handle;
7803             native_buffer[nPortIndex].nativehandle = handle;
7804         } else {
7805             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
7806             return OMX_ErrorBadParameter;
7807         }
7808 
7809         if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
7810             m_is_display_session = true;
7811         } else {
7812             m_is_display_session = false;
7813         }
7814         buffer->nAllocLen = handle->size;
7815         DEBUG_PRINT_LOW("%s: buffer size = d-%d:b-%d",
7816                         __func__, (int)drv_ctx.op_buf.buffer_size, (int)handle->size);
7817 
7818         if (!client_buffers.is_color_conversion_enabled()) {
7819             drv_ctx.op_buf.buffer_size = handle->size;
7820         }
7821 
7822         DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
7823     }
7824 
7825     if (client_buffers.is_color_conversion_enabled()) {
7826         buffer = m_intermediate_out_mem_ptr + nPortIndex;
7827         buffer->nAllocLen = drv_ctx.op_buf.buffer_size;
7828     }
7829 
7830     //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
7831     //this with a more sane size so that we don't compensate in rest of code
7832     //We'll restore this size later on, so that it's transparent to client
7833     buffer->nFilledLen = 0;
7834 
7835     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
7836     return OMX_ErrorNone;
7837 }
7838 
7839 /* ======================================================================
7840    FUNCTION
7841    omx_vdec::fill_this_buffer_proxy
7842 
7843    DESCRIPTION
7844    IL client uses this method to release the frame buffer
7845    after displaying them.
7846 
7847    PARAMETERS
7848    None.
7849 
7850    RETURN VALUE
7851    true/false
7852 
7853    ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)7854 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
7855         OMX_IN OMX_HANDLETYPE        hComp,
7856         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
7857 {
7858     VIDC_TRACE_NAME_HIGH("FTB");
7859     OMX_ERRORTYPE nRet = OMX_ErrorNone;
7860     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
7861     unsigned bufIndex = 0;
7862     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
7863     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
7864 
7865     auto_lock l(buf_lock);
7866     OMX_BUFFERHEADERTYPE  *omx_base_address =
7867         client_buffers.is_color_conversion_enabled()?
7868                            m_intermediate_out_mem_ptr:m_out_mem_ptr;
7869     vdec_bufferpayload *omx_ptr_outputbuffer =
7870         client_buffers.is_color_conversion_enabled()?
7871                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
7872     bufIndex = buffer-omx_base_address;
7873 
7874     if (bufferAdd == NULL || bufIndex >= drv_ctx.op_buf.actualcount) {
7875         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, bufIndex %u bufCount %u",
7876             bufIndex, drv_ctx.op_buf.actualcount);
7877         return OMX_ErrorBadParameter;
7878     }
7879 
7880     if (BITMASK_ABSENT(&m_out_bm_count, bufIndex) || m_buffer_error) {
7881         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, bufIndex %u", bufIndex);
7882         return OMX_ErrorBadParameter;
7883     }
7884 
7885     /*Return back the output buffer to client*/
7886     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) {
7887         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
7888         buffer->nFilledLen = 0;
7889         print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7890         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7891         return OMX_ErrorNone;
7892     }
7893     if (m_error_propogated == true) {
7894         DEBUG_PRINT_LOW("Return buffers in error state");
7895         buffer->nFilledLen = 0;
7896         print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7897         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7898         return OMX_ErrorNone;
7899     }
7900 
7901     if (dynamic_buf_mode) {
7902         omx_ptr_outputbuffer[bufIndex].offset = 0;
7903         omx_ptr_outputbuffer[bufIndex].buffer_len = buffer->nAllocLen;
7904         omx_ptr_outputbuffer[bufIndex].mmaped_size = buffer->nAllocLen;
7905     }
7906 
7907     pending_output_buffers++;
7908     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7909     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
7910     if (ptr_respbuffer) {
7911         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
7912     }
7913 
7914     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
7915         DEBUG_PRINT_ERROR("Invalid ptr_respbuffer %p, ptr_outputbuffer %p",
7916             ptr_respbuffer, ptr_outputbuffer);
7917         buffer->nFilledLen = 0;
7918         print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7919         m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7920         pending_output_buffers--;
7921         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7922         return OMX_ErrorBadParameter;
7923     }
7924 
7925     int rc = 0;
7926     struct v4l2_buffer buf;
7927     struct v4l2_plane plane[VIDEO_MAX_PLANES];
7928     memset( (void *)&buf, 0, sizeof(buf));
7929     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
7930     unsigned int extra_idx = 0;
7931 
7932     buf.index = bufIndex;
7933     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7934     buf.memory = V4L2_MEMORY_USERPTR;
7935     plane[0].bytesused = buffer->nFilledLen;
7936     plane[0].length = buffer->nAllocLen;
7937     plane[0].m.userptr =
7938         (unsigned long)omx_ptr_outputbuffer[bufIndex].bufferaddr -
7939         (unsigned long)omx_ptr_outputbuffer[bufIndex].offset;
7940     plane[0].reserved[0] = omx_ptr_outputbuffer[bufIndex].pmem_fd;
7941     plane[0].reserved[1] = omx_ptr_outputbuffer[bufIndex].offset;
7942     plane[0].data_offset = 0;
7943     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7944     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7945         plane[extra_idx].bytesused = 0;
7946         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
7947         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + bufIndex * drv_ctx.extradata_info.buffer_size);
7948 #ifdef USE_ION
7949         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.data_fd;
7950 #endif
7951         plane[extra_idx].reserved[1] = bufIndex * drv_ctx.extradata_info.buffer_size;
7952         plane[extra_idx].data_offset = 0;
7953     } else if (extra_idx >= VIDEO_MAX_PLANES) {
7954         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
7955         return OMX_ErrorBadParameter;
7956     }
7957     buf.m.planes = plane;
7958     buf.length = drv_ctx.num_planes;
7959     print_v4l2_buffer("QBUF-FTB", &buf);
7960     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7961     if (rc) {
7962         buffer->nFilledLen = 0;
7963         DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno));
7964         print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7965         m_cb.FillBufferDone(hComp, m_app_data, &m_out_mem_ptr[bufIndex]);
7966         return OMX_ErrorHardware;
7967     }
7968 
7969     return OMX_ErrorNone;
7970 }
7971 
7972 /* ======================================================================
7973    FUNCTION
7974    omx_vdec::SetCallbacks
7975 
7976    DESCRIPTION
7977    Set the callbacks.
7978 
7979    PARAMETERS
7980    None.
7981 
7982    RETURN VALUE
7983    OMX Error None if everything successful.
7984 
7985    ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)7986 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
7987         OMX_IN OMX_CALLBACKTYPE* callbacks,
7988         OMX_IN OMX_PTR             appData)
7989 {
7990     (void) hComp;
7991 
7992     if (!callbacks)
7993         return OMX_ErrorBadParameter;
7994 
7995     m_cb       = *callbacks;
7996     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
7997             m_cb.EventHandler,m_cb.FillBufferDone);
7998     m_app_data =    appData;
7999     return OMX_ErrorNone;
8000 }
8001 
8002 /* ======================================================================
8003    FUNCTION
8004    omx_vdec::ComponentDeInit
8005 
8006    DESCRIPTION
8007    Destroys the component and release memory allocated to the heap.
8008 
8009    PARAMETERS
8010    <TBD>.
8011 
8012    RETURN VALUE
8013    OMX Error None if everything successful.
8014 
8015    ========================================================================== */
component_deinit(OMX_IN OMX_HANDLETYPE hComp)8016 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
8017 {
8018    (void) hComp;
8019    OMX_ERRORTYPE nRet = OMX_ErrorNone;
8020    OMX_BUFFERHEADERTYPE *buffer;
8021 
8022     unsigned i = 0;
8023     if (OMX_StateLoaded != m_state) {
8024         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
8025                 m_state);
8026         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
8027     } else {
8028         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
8029     }
8030 
8031     /*Check if the output buffers have to be cleaned up*/
8032     buffer = m_out_mem_ptr;
8033     if (buffer) {
8034         DEBUG_PRINT_LOW("Freeing the Output Memory");
8035         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
8036             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
8037                 BITMASK_CLEAR(&m_out_bm_count, i);
8038                     nRet = free_output_buffer (buffer+i);
8039                     if (OMX_ErrorNone != nRet)
8040                         break;
8041             }
8042             if (release_output_done()) {
8043                 DEBUG_PRINT_HIGH("All output buffers are released");
8044                 break;
8045             }
8046         }
8047 #ifdef _ANDROID_ICS_
8048         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
8049 #endif
8050     }
8051 
8052     /*Check if the input buffers have to be cleaned up*/
8053     if (m_inp_mem_ptr || m_inp_heap_ptr) {
8054         DEBUG_PRINT_LOW("Freeing the Input Memory");
8055         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
8056 
8057             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
8058                 BITMASK_CLEAR(&m_inp_bm_count, i);
8059                 if (m_inp_mem_ptr)
8060                     free_input_buffer (i,&m_inp_mem_ptr[i]);
8061                 else
8062                     free_input_buffer (i,NULL);
8063             }
8064 
8065             if (release_input_done()) {
8066                 DEBUG_PRINT_HIGH("All input buffers released");
8067                 break;
8068             }
8069        }
8070     }
8071     free_input_buffer_header();
8072     free_output_buffer_header();
8073     if (h264_scratch.pBuffer) {
8074         free(h264_scratch.pBuffer);
8075         h264_scratch.pBuffer = NULL;
8076     }
8077 
8078     if (h264_parser) {
8079         delete h264_parser;
8080         h264_parser = NULL;
8081     }
8082 
8083     if (m_frame_parser.mutils) {
8084         DEBUG_PRINT_LOW("Free utils parser");
8085         delete (m_frame_parser.mutils);
8086         m_frame_parser.mutils = NULL;
8087     }
8088 
8089     if (m_platform_list) {
8090         free(m_platform_list);
8091         m_platform_list = NULL;
8092     }
8093     if (m_vendor_config.pData) {
8094         free(m_vendor_config.pData);
8095         m_vendor_config.pData = NULL;
8096     }
8097 
8098     // Reset counters in mesg queues
8099     m_ftb_q.m_size=0;
8100     m_cmd_q.m_size=0;
8101     m_etb_q.m_size=0;
8102     m_ftb_q.m_read = m_ftb_q.m_write =0;
8103     m_cmd_q.m_read = m_cmd_q.m_write =0;
8104     m_etb_q.m_read = m_etb_q.m_write =0;
8105 
8106     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
8107     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
8108     // NULL);
8109     DEBUG_PRINT_HIGH("Close the driver instance");
8110 
8111     if (m_debug.infile) {
8112         fclose(m_debug.infile);
8113         m_debug.infile = NULL;
8114     }
8115     if (m_debug.outfile) {
8116         fclose(m_debug.outfile);
8117         m_debug.outfile = NULL;
8118     }
8119     if (m_debug.ccoutfile) {
8120         fclose(m_debug.ccoutfile);
8121         m_debug.ccoutfile = NULL;
8122     }
8123     if (m_debug.out_ymeta_file) {
8124         fclose(m_debug.out_ymeta_file);
8125         m_debug.out_ymeta_file = NULL;
8126     }
8127     if (m_debug.out_uvmeta_file) {
8128         fclose(m_debug.out_uvmeta_file);
8129         m_debug.out_uvmeta_file = NULL;
8130     }
8131 #ifdef OUTPUT_EXTRADATA_LOG
8132     if (outputExtradataFile)
8133         fclose (outputExtradataFile);
8134 #endif
8135     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
8136     return OMX_ErrorNone;
8137 }
8138 
8139 /* ======================================================================
8140    FUNCTION
8141    omx_vdec::UseEGLImage
8142 
8143    DESCRIPTION
8144    OMX Use EGL Image method implementation <TBD>.
8145 
8146    PARAMETERS
8147    <TBD>.
8148 
8149    RETURN VALUE
8150    Not Implemented error.
8151 
8152    ========================================================================== */
use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN void * eglImage)8153 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
8154         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
8155         OMX_IN OMX_U32                        port,
8156         OMX_IN OMX_PTR                     appData,
8157         OMX_IN void*                      eglImage)
8158 {
8159     (void) appData;
8160     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
8161     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
8162     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
8163 
8164 #ifdef USE_EGL_IMAGE_GPU
8165     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
8166     EGLint fd = -1, offset = 0,pmemPtr = 0;
8167 #else
8168     int fd = -1, offset = 0;
8169 #endif
8170     DEBUG_PRINT_HIGH("use EGL image support for decoder");
8171     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
8172         DEBUG_PRINT_ERROR("Invalid EGL image");
8173     }
8174 #ifdef USE_EGL_IMAGE_GPU
8175     if (m_display_id == NULL) {
8176         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
8177         return OMX_ErrorInsufficientResources;
8178     }
8179     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
8180         eglGetProcAddress("eglQueryImageKHR");
8181     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
8182     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
8183     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
8184 #else //with OMX test app
8185     struct temp_egl {
8186         int pmem_fd;
8187         int offset;
8188     };
8189     struct temp_egl *temp_egl_id = NULL;
8190     void * pmemPtr = (void *) eglImage;
8191     temp_egl_id = (struct temp_egl *)eglImage;
8192     if (temp_egl_id != NULL) {
8193         fd = temp_egl_id->pmem_fd;
8194         offset = temp_egl_id->offset;
8195     }
8196 #endif
8197     if (fd < 0) {
8198         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
8199         return OMX_ErrorInsufficientResources;
8200     }
8201     pmem_info.pmem_fd = (OMX_U32) fd;
8202     pmem_info.offset = (OMX_U32) offset;
8203     pmem_entry.entry = (void *) &pmem_info;
8204     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8205     pmem_list.entryList = &pmem_entry;
8206     pmem_list.nEntries = 1;
8207     ouput_egl_buffers = true;
8208     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
8209                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
8210                 (OMX_U8 *)pmemPtr)) {
8211         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
8212         return OMX_ErrorInsufficientResources;
8213     }
8214     return OMX_ErrorNone;
8215 }
8216 
8217 /* ======================================================================
8218    FUNCTION
8219    omx_vdec::ComponentRoleEnum
8220 
8221    DESCRIPTION
8222    OMX Component Role Enum method implementation.
8223 
8224    PARAMETERS
8225    <TBD>.
8226 
8227    RETURN VALUE
8228    OMX Error None if everything is successful.
8229    ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)8230 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
8231         OMX_OUT OMX_U8*        role,
8232         OMX_IN OMX_U32        index)
8233 {
8234     (void) hComp;
8235     OMX_ERRORTYPE eRet = OMX_ErrorNone;
8236 
8237     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
8238         if ((0 == index) && role) {
8239             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
8240             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8241         } else {
8242             eRet = OMX_ErrorNoMore;
8243         }
8244     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
8245         if ((0 == index) && role) {
8246             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
8247             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8248         } else {
8249             DEBUG_PRINT_LOW("No more roles");
8250             eRet = OMX_ErrorNoMore;
8251         }
8252     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
8253         if ((0 == index) && role) {
8254             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
8255             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8256         } else {
8257             DEBUG_PRINT_LOW("No more roles");
8258             eRet = OMX_ErrorNoMore;
8259         }
8260     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
8261         if ((0 == index) && role) {
8262             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
8263             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
8264         } else {
8265             DEBUG_PRINT_LOW("No more roles");
8266             eRet = OMX_ErrorNoMore;
8267         }
8268     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
8269         if ((0 == index) && role) {
8270             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
8271             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8272         } else {
8273             DEBUG_PRINT_LOW("No more roles");
8274             eRet = OMX_ErrorNoMore;
8275         }
8276     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
8277         if ((0 == index) && role) {
8278             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
8279             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8280         } else {
8281             DEBUG_PRINT_LOW("No more roles");
8282             eRet = OMX_ErrorNoMore;
8283         }
8284     } else {
8285         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
8286         eRet = OMX_ErrorInvalidComponentName;
8287     }
8288     return eRet;
8289 }
8290 
8291 
8292 
8293 
8294 /* ======================================================================
8295    FUNCTION
8296    omx_vdec::AllocateDone
8297 
8298    DESCRIPTION
8299    Checks if entire buffer pool is allocated by IL Client or not.
8300    Need this to move to IDLE state.
8301 
8302    PARAMETERS
8303    None.
8304 
8305    RETURN VALUE
8306    true/false.
8307 
8308    ========================================================================== */
allocate_done(void)8309 bool omx_vdec::allocate_done(void)
8310 {
8311     bool bRet = false;
8312     bool bRet_In = false;
8313     bool bRet_Out = false;
8314     bool bRet_Out_Extra = false;
8315 
8316     bRet_In = allocate_input_done();
8317     bRet_Out = allocate_output_done();
8318     bRet_Out_Extra = allocate_output_extradata_done();
8319 
8320     if (bRet_In && bRet_Out && bRet_Out_Extra) {
8321         DEBUG_PRINT_HIGH("All ports buffers are allocated");
8322         bRet = true;
8323     }
8324 
8325     return bRet;
8326 }
8327 /* ======================================================================
8328    FUNCTION
8329    omx_vdec::AllocateInputDone
8330 
8331    DESCRIPTION
8332    Checks if I/P buffer pool is allocated by IL Client or not.
8333 
8334    PARAMETERS
8335    None.
8336 
8337    RETURN VALUE
8338    true/false.
8339 
8340    ========================================================================== */
allocate_input_done(void)8341 bool omx_vdec::allocate_input_done(void)
8342 {
8343     bool bRet = false;
8344     unsigned i=0;
8345 
8346     if (m_inp_mem_ptr == NULL) {
8347         return bRet;
8348     }
8349     if (m_inp_mem_ptr ) {
8350         for (; i<drv_ctx.ip_buf.actualcount; i++) {
8351             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
8352                 break;
8353             }
8354         }
8355     }
8356     if (i == drv_ctx.ip_buf.actualcount) {
8357         bRet = true;
8358     }
8359     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
8360         m_inp_bPopulated = OMX_TRUE;
8361     }
8362     return bRet;
8363 }
8364 /* ======================================================================
8365    FUNCTION
8366    omx_vdec::AllocateOutputDone
8367 
8368    DESCRIPTION
8369    Checks if entire O/P buffer pool is allocated by IL Client or not.
8370 
8371    PARAMETERS
8372    None.
8373 
8374    RETURN VALUE
8375    true/false.
8376 
8377    ========================================================================== */
allocate_output_done(void)8378 bool omx_vdec::allocate_output_done(void)
8379 {
8380     bool bRet = false;
8381     unsigned j=0;
8382 
8383     if (m_out_mem_ptr == NULL) {
8384         return bRet;
8385     }
8386 
8387     if (m_out_mem_ptr) {
8388         for (; j < drv_ctx.op_buf.actualcount; j++) {
8389             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
8390                 break;
8391             }
8392         }
8393     }
8394 
8395     if (j == drv_ctx.op_buf.actualcount) {
8396         bRet = true;
8397         if (m_out_bEnabled)
8398             m_out_bPopulated = OMX_TRUE;
8399     }
8400 
8401     return bRet;
8402 }
8403 
allocate_output_extradata_done(void)8404 bool omx_vdec::allocate_output_extradata_done(void) {
8405     bool bRet = false;
8406     unsigned j=0;
8407     unsigned nBufferCount = 0;
8408 
8409     nBufferCount = m_client_out_extradata_info.getBufferCount();
8410 
8411     if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
8412         return true;
8413     }
8414 
8415     if (m_client_output_extradata_mem_ptr) {
8416         for (; j < nBufferCount; j++) {
8417             if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
8418                 break;
8419             }
8420         }
8421 
8422         if (j == nBufferCount) {
8423             bRet = true;
8424             DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
8425         }
8426     }
8427 
8428     return bRet;
8429 }
8430 /* ======================================================================
8431    FUNCTION
8432    omx_vdec::ReleaseDone
8433 
8434    DESCRIPTION
8435    Checks if IL client has released all the buffers.
8436 
8437    PARAMETERS
8438    None.
8439 
8440    RETURN VALUE
8441    true/false
8442 
8443    ========================================================================== */
release_done(void)8444 bool omx_vdec::release_done(void)
8445 {
8446     bool bRet = false;
8447 
8448     if (release_input_done()) {
8449         if (release_output_done()) {
8450             if (release_output_extradata_done()) {
8451                 DEBUG_PRINT_HIGH("All ports buffers are released");
8452                 bRet = true;
8453             }
8454         }
8455     }
8456     return bRet;
8457 }
8458 
8459 
8460 /* ======================================================================
8461    FUNCTION
8462    omx_vdec::ReleaseOutputDone
8463 
8464    DESCRIPTION
8465    Checks if IL client has released all the buffers.
8466 
8467    PARAMETERS
8468    None.
8469 
8470    RETURN VALUE
8471    true/false
8472 
8473    ========================================================================== */
release_output_done(void)8474 bool omx_vdec::release_output_done(void)
8475 {
8476     bool bRet = false;
8477     unsigned i=0,j=0;
8478 
8479     if (m_out_mem_ptr) {
8480         for (; j < drv_ctx.op_buf.actualcount ; j++) {
8481             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
8482                 break;
8483             }
8484         }
8485         if (j == drv_ctx.op_buf.actualcount) {
8486             m_out_bm_count = 0;
8487             bRet = true;
8488         }
8489     } else {
8490         m_out_bm_count = 0;
8491         bRet = true;
8492     }
8493     return bRet;
8494 }
8495 /* ======================================================================
8496    FUNCTION
8497    omx_vdec::ReleaseInputDone
8498 
8499    DESCRIPTION
8500    Checks if IL client has released all the buffers.
8501 
8502    PARAMETERS
8503    None.
8504 
8505    RETURN VALUE
8506    true/false
8507 
8508    ========================================================================== */
release_input_done(void)8509 bool omx_vdec::release_input_done(void)
8510 {
8511     bool bRet = false;
8512     unsigned i=0,j=0;
8513 
8514     if (m_inp_mem_ptr) {
8515         for (; j<drv_ctx.ip_buf.actualcount; j++) {
8516             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
8517                 break;
8518             }
8519         }
8520         if (j==drv_ctx.ip_buf.actualcount) {
8521             bRet = true;
8522         }
8523     } else {
8524         bRet = true;
8525     }
8526     return bRet;
8527 }
8528 
release_output_extradata_done(void)8529 bool omx_vdec::release_output_extradata_done(void) {
8530     bool bRet = false;
8531     unsigned i=0,j=0, buffer_count=0;
8532 
8533     buffer_count = m_client_out_extradata_info.getBufferCount();
8534     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
8535             m_client_output_extradata_mem_ptr, buffer_count);
8536 
8537     if (m_client_output_extradata_mem_ptr) {
8538         for (; j<buffer_count; j++) {
8539             if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
8540                 break;
8541             }
8542         }
8543         if (j == buffer_count) {
8544             bRet = true;
8545         }
8546     } else {
8547         bRet = true;
8548     }
8549     return bRet;
8550 }
8551 
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)8552 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
8553         OMX_BUFFERHEADERTYPE * buffer)
8554 {
8555     VIDC_TRACE_NAME_HIGH("FBD");
8556     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
8557     OMX_BUFFERHEADERTYPE  *omx_base_address =
8558         client_buffers.is_color_conversion_enabled()?
8559                               m_intermediate_out_mem_ptr:m_out_mem_ptr;
8560     vdec_bufferpayload *omx_ptr_outputbuffer =
8561         client_buffers.is_color_conversion_enabled()?
8562                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
8563 
8564     if (!buffer || (buffer - omx_base_address) >= (int)drv_ctx.op_buf.actualcount) {
8565         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
8566         return OMX_ErrorBadParameter;
8567     } else if (output_flush_progress) {
8568         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
8569         buffer->nFilledLen = 0;
8570         buffer->nTimeStamp = 0;
8571         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8572         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
8573         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
8574     }
8575 
8576     if (m_debug_extradata) {
8577         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
8578             DEBUG_PRINT_HIGH("***************************************************");
8579             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
8580             DEBUG_PRINT_HIGH("***************************************************");
8581         }
8582 
8583         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
8584             DEBUG_PRINT_HIGH("***************************************************");
8585             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8586             DEBUG_PRINT_HIGH("***************************************************");
8587         }
8588     }
8589 
8590     pending_output_buffers --;
8591     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
8592 
8593     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8594         DEBUG_PRINT_HIGH("Output EOS has been reached");
8595         if (!output_flush_progress)
8596             post_event((unsigned)NULL, (unsigned)NULL,
8597                     OMX_COMPONENT_GENERATE_EOS_DONE);
8598 
8599         if (psource_frame) {
8600             print_omx_buffer("EBD in FBD", psource_frame);
8601             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
8602             psource_frame = NULL;
8603         }
8604         if (pdest_frame) {
8605             pdest_frame->nFilledLen = 0;
8606             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
8607                     (unsigned)NULL);
8608             pdest_frame = NULL;
8609         }
8610     }
8611 
8612 #ifdef OUTPUT_EXTRADATA_LOG
8613     if (outputExtradataFile) {
8614         int buf_index = buffer - omx_base_address;
8615         OMX_U8 *pBuffer = (OMX_U8 *)(omx_ptr_outputbuffer[buf_index].bufferaddr);
8616 
8617         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
8618         p_extra = (OMX_OTHER_EXTRADATATYPE *)
8619             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
8620 
8621         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
8622             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
8623                                     p_extra->nSize, p_extra->eType);
8624             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
8625 
8626             if (p_extra->eType == OMX_ExtraDataNone) {
8627                 break;
8628             }
8629             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8630         }
8631     }
8632 #endif
8633 
8634     /* For use buffer we need to copy the data */
8635     if (!output_flush_progress) {
8636         /* This is the error check for non-recoverable errros */
8637         bool is_duplicate_ts_valid = true;
8638         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
8639 
8640         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
8641                 output_capability == V4L2_PIX_FMT_MPEG2)
8642             is_duplicate_ts_valid = false;
8643 
8644         if (buffer->nFilledLen > 0) {
8645             time_stamp_dts.get_next_timestamp(buffer,
8646                     is_interlaced && is_duplicate_ts_valid && !is_mbaff);
8647         }
8648     }
8649     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
8650 
8651     if (m_cb.FillBufferDone) {
8652         if (buffer->nFilledLen > 0) {
8653             if (arbitrary_bytes)
8654                 adjust_timestamp(buffer->nTimeStamp);
8655             else
8656                 set_frame_rate(buffer->nTimeStamp);
8657 
8658             proc_frms++;
8659             if (perf_flag) {
8660                 if (1 == proc_frms) {
8661                     dec_time.stop();
8662                     latency = dec_time.processing_time_us() - latency;
8663                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
8664                     dec_time.start();
8665                     fps_metrics.start();
8666                 }
8667                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8668                     OMX_U64 proc_time = 0;
8669                     fps_metrics.stop();
8670                     proc_time = fps_metrics.processing_time_us();
8671                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
8672                             (unsigned int)proc_frms, (float)proc_time / 1e6,
8673                             (float)(1e6 * proc_frms) / proc_time);
8674                 }
8675             }
8676         }
8677         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8678             prev_ts = LLONG_MAX;
8679             rst_prev_ts = true;
8680             proc_frms = 0;
8681         }
8682 
8683         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8684             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
8685              buffer->pPlatformPrivate)->entryList->entry;
8686         OMX_BUFFERHEADERTYPE *il_buffer;
8687         il_buffer = client_buffers.get_il_buf_hdr(buffer);
8688         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
8689 
8690         if (il_buffer && m_last_rendered_TS >= 0) {
8691             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
8692             // Convert fps into ms value. 1 sec = 1000000 ms.
8693             OMX_U64 target_ts_delta = m_dec_hfr_fps ? 1000000 / m_dec_hfr_fps : ts_delta;
8694 
8695             // Current frame can be send for rendering if
8696             // (a) current FPS is <=  60
8697             // (b) is the next frame after the frame with TS 0
8698             // (c) is the first frame after seek
8699             // (d) the delta TS b\w two consecutive frames is > 16 ms
8700             // (e) its TS is equal to previous frame TS
8701             // (f) if marked EOS
8702 
8703             if(current_framerate <= (OMX_U32)m_dec_hfr_fps || m_last_rendered_TS == 0 ||
8704                il_buffer->nTimeStamp == 0 || ts_delta >= (OMX_TICKS)target_ts_delta||
8705                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
8706                m_last_rendered_TS = il_buffer->nTimeStamp;
8707             } else {
8708                //mark for droping
8709                buffer->nFilledLen = 0;
8710             }
8711 
8712             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
8713                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
8714                               il_buffer->nTimeStamp,ts_delta);
8715 
8716             //above code makes sure that delta b\w two consecutive frames is not
8717             //greater than 16ms, slow-mo feature, so cap fps to max 60
8718             if (current_framerate > (OMX_U32)m_dec_hfr_fps ) {
8719                 current_framerate = m_dec_hfr_fps;
8720             }
8721         }
8722 
8723         // add current framerate to gralloc meta data
8724         if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && omx_base_address) {
8725             // If valid fps was received, directly send it to display for the 1st fbd.
8726             // Otherwise, calculate fps using fbd timestamps
8727             float refresh_rate = m_fps_prev;
8728             if (m_fps_received) {
8729                 if (1 == proc_frms) {
8730                     refresh_rate = m_fps_received / (float)(1<<16);
8731                 }
8732             } else {
8733                 // calculate and set refresh rate for every frame from second frame onwards
8734                 // display will assume the default refresh rate for first frame (which is 60 fps)
8735                 if (m_fps_prev) {
8736                     if (drv_ctx.frame_rate.fps_denominator) {
8737                         refresh_rate = drv_ctx.frame_rate.fps_numerator /
8738                             (float) drv_ctx.frame_rate.fps_denominator;
8739                     }
8740                 }
8741             }
8742             OMX_U32 fps_limit = m_dec_hfr_fps ? (OMX_U32)m_dec_hfr_fps : 60;
8743             if (refresh_rate > fps_limit) {
8744                 refresh_rate = fps_limit;
8745             }
8746             DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
8747             OMX_U32 buf_index = buffer - omx_base_address;
8748             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8749                          UPDATE_REFRESH_RATE, (void*)&refresh_rate);
8750             m_fps_prev = refresh_rate;
8751         }
8752 
8753         if (buffer->nFilledLen && m_enable_android_native_buffers && omx_base_address) {
8754             OMX_U32 buf_index = buffer - omx_base_address;
8755             DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
8756             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8757                                S3D_FORMAT, (void*)&stereo_output_mode);
8758         }
8759 
8760         if (il_buffer) {
8761             log_output_buffers(buffer);
8762             log_cc_output_buffers(il_buffer);
8763             if (dynamic_buf_mode) {
8764                 unsigned int nPortIndex = 0;
8765                 nPortIndex = buffer-omx_base_address;
8766 
8767                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
8768                 // to size of the handle. Do it _after_ log_output_buffers which
8769                 // requires the respective sizes to be accurate.
8770 
8771                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
8772                 buffer->nFilledLen = buffer->nFilledLen ?
8773                         sizeof(struct VideoDecoderOutputMetaData) : 0;
8774 
8775                 //Clear graphic buffer handles in dynamic mode
8776                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
8777                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
8778                     native_buffer[nPortIndex].privatehandle = NULL;
8779                     native_buffer[nPortIndex].nativehandle = NULL;
8780                 } else {
8781                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
8782                     return OMX_ErrorBadParameter;
8783                 }
8784             }
8785             print_omx_buffer("FillBufferDone", buffer);
8786             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
8787         } else {
8788             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
8789             return OMX_ErrorBadParameter;
8790         }
8791     } else {
8792         DEBUG_PRINT_ERROR("NULL m_cb.FillBufferDone");
8793         return OMX_ErrorBadParameter;
8794     }
8795 
8796 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
8797     if (m_smoothstreaming_mode && omx_base_address) {
8798         OMX_U32 buf_index = buffer - omx_base_address;
8799         BufferDim_t dim;
8800         private_handle_t *private_handle = NULL;
8801         dim.sliceWidth = framesize.nWidth;
8802         dim.sliceHeight = framesize.nHeight;
8803         if (buf_index < drv_ctx.op_buf.actualcount &&
8804             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
8805             native_buffer[buf_index].privatehandle)
8806             private_handle = native_buffer[buf_index].privatehandle;
8807         if (private_handle) {
8808             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
8809                 dim.sliceWidth, dim.sliceHeight);
8810             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
8811         }
8812     }
8813 #endif
8814 
8815     return OMX_ErrorNone;
8816 }
8817 
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)8818 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
8819         OMX_BUFFERHEADERTYPE* buffer)
8820 {
8821     VIDC_TRACE_NAME_HIGH("EBD");
8822     int nBufferIndex = buffer - m_inp_mem_ptr;
8823 
8824     if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
8825         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
8826         return OMX_ErrorBadParameter;
8827     }
8828 
8829     pending_input_buffers--;
8830     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
8831 
8832     if (arbitrary_bytes) {
8833         if (pdest_frame == NULL && input_flush_progress == false) {
8834             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
8835             pdest_frame = buffer;
8836             buffer->nFilledLen = 0;
8837             buffer->nTimeStamp = LLONG_MAX;
8838             push_input_buffer (hComp);
8839         } else {
8840             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
8841             buffer->nFilledLen = 0;
8842             if (!m_input_free_q.insert_entry((unsigned long)buffer,
8843                         (unsigned)NULL, (unsigned)NULL)) {
8844                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
8845             }
8846         }
8847     } else if (m_cb.EmptyBufferDone) {
8848         buffer->nFilledLen = 0;
8849         if (input_use_buffer == true) {
8850             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
8851         }
8852 
8853         /* Restore the FD that we over-wrote in ETB */
8854         if (m_input_pass_buffer_fd) {
8855             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
8856         }
8857 
8858         print_omx_buffer("EmptyBufferDone", buffer);
8859         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
8860     }
8861     return OMX_ErrorNone;
8862 }
8863 
async_message_process(void * context,void * message)8864 int omx_vdec::async_message_process (void *context, void* message)
8865 {
8866     omx_vdec* omx = NULL;
8867     struct vdec_msginfo *vdec_msg = NULL;
8868     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
8869     struct v4l2_buffer *v4l2_buf_ptr = NULL;
8870     struct v4l2_plane *plane = NULL;
8871     struct vdec_output_frameinfo *output_respbuf = NULL;
8872     int rc=1;
8873     bool reconfig_event_sent = false;
8874     if (context == NULL || message == NULL) {
8875         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
8876         return -1;
8877     }
8878     vdec_msg = (struct vdec_msginfo *)message;
8879 
8880     omx = reinterpret_cast<omx_vdec*>(context);
8881 
8882     switch (vdec_msg->msgcode) {
8883 
8884         case VDEC_MSG_EVT_HW_ERROR:
8885             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8886                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8887             break;
8888 
8889         case VDEC_MSG_EVT_HW_OVERLOAD:
8890             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8891                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
8892             break;
8893 
8894         case VDEC_MSG_EVT_HW_UNSUPPORTED:
8895             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8896                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
8897             break;
8898 
8899         case VDEC_MSG_RESP_START_DONE:
8900             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8901                     OMX_COMPONENT_GENERATE_START_DONE);
8902             break;
8903 
8904         case VDEC_MSG_RESP_STOP_DONE:
8905             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8906                     OMX_COMPONENT_GENERATE_STOP_DONE);
8907             break;
8908 
8909         case VDEC_MSG_RESP_RESUME_DONE:
8910             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8911                     OMX_COMPONENT_GENERATE_RESUME_DONE);
8912             break;
8913 
8914         case VDEC_MSG_RESP_PAUSE_DONE:
8915             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8916                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
8917             break;
8918 
8919         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
8920             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8921                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
8922             break;
8923         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
8924             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8925                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
8926             break;
8927         case VDEC_MSG_RESP_INPUT_FLUSHED:
8928         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
8929 
8930             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
8931                vdec_msg->msgdata.input_frame_clientdata; */
8932 
8933             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
8934             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
8935                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
8936                 omxhdr = NULL;
8937                 vdec_msg->status_code = VDEC_S_EFATAL;
8938                 break;
8939 
8940             }
8941             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
8942 
8943             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
8944                 DEBUG_PRINT_HIGH("Unsupported input");
8945                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8946                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8947             }
8948             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
8949                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8950                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
8951             }
8952             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
8953 
8954                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
8955                 android_atomic_dec(&omx->m_queued_codec_config_count);
8956                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
8957                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
8958                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
8959                     sem_post(&omx->m_safe_flush);
8960                 }
8961             }
8962             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
8963                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
8964             }
8965             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
8966                     OMX_COMPONENT_GENERATE_EBD);
8967             break;
8968         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
8969             int64_t *timestamp;
8970             timestamp = (int64_t *) malloc(sizeof(int64_t));
8971             if (timestamp) {
8972                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
8973                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
8974                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
8975                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
8976                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
8977             }
8978             break;
8979         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
8980         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: {
8981            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
8982 
8983            OMX_BUFFERHEADERTYPE  *omx_base_address = omx->m_out_mem_ptr;
8984            vdec_bufferpayload *omx_ptr_outputbuffer = omx->drv_ctx.ptr_outputbuffer;
8985            vdec_output_frameinfo *omx_ptr_respbuffer = omx->drv_ctx.ptr_respbuffer;
8986 
8987            if (omx->client_buffers.is_color_conversion_enabled()) {
8988                omx_base_address = omx->m_intermediate_out_mem_ptr;
8989                omx_ptr_outputbuffer = omx->drv_ctx.ptr_intermediate_outputbuffer;
8990                omx_ptr_respbuffer = omx->drv_ctx.ptr_intermediate_respbuffer;
8991            }
8992 
8993            if (v4l2_buf_ptr == NULL || omx_base_address == NULL ||
8994                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
8995                omxhdr = NULL;
8996                vdec_msg->status_code = VDEC_S_EFATAL;
8997                break;
8998            }
8999            plane = v4l2_buf_ptr->m.planes;
9000            omxhdr = omx_base_address + v4l2_buf_ptr->index;
9001 
9002            if (omxhdr && omxhdr->pOutputPortPrivate &&
9003                ((omxhdr - omx_base_address) < (int)omx->drv_ctx.op_buf.actualcount) &&
9004                    (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
9005                      - omx_ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
9006 
9007                omxhdr->pMarkData = (OMX_PTR)(unsigned long)plane[0].reserved[3];
9008                omxhdr->hMarkTargetComponent = (OMX_HANDLETYPE)(unsigned long)plane[0].reserved[4];
9009 
9010                if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
9011                    omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
9012                } else {
9013                    DEBUG_PRINT_ERROR("Invalid filled length = %u, set it as buffer size = %u",
9014                            (unsigned int)vdec_msg->msgdata.output_frame.len, omxhdr->nAllocLen);
9015                    omxhdr->nFilledLen = omxhdr->nAllocLen;
9016                }
9017                    omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
9018                    omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
9019                    omxhdr->nFlags = 0;
9020 
9021                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
9022                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
9023                         //rc = -1;
9024                    }
9025                    if (omxhdr->nFilledLen) {
9026                        omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
9027                    }
9028                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
9029                        omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
9030                    } else {
9031                        omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
9032                    }
9033 #if NEED_TO_REVISIT
9034                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
9035                        omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
9036                    }
9037 #endif
9038                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
9039                         omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
9040                         DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
9041                                         omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
9042                    }
9043 
9044                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
9045                        omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
9046                    }
9047 
9048                    output_respbuf = (struct vdec_output_frameinfo *)\
9049                             omxhdr->pOutputPortPrivate;
9050                    if (!output_respbuf) {
9051                      DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
9052                      return -1;
9053                    }
9054                    output_respbuf->len = vdec_msg->msgdata.output_frame.len;
9055                    output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
9056 
9057                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
9058                        output_respbuf->pic_type = PICTURE_TYPE_I;
9059                    }
9060                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
9061                        output_respbuf->pic_type = PICTURE_TYPE_P;
9062                    }
9063                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
9064                        output_respbuf->pic_type = PICTURE_TYPE_B;
9065                    }
9066 
9067                    if (vdec_msg->msgdata.output_frame.len) {
9068                        DEBUG_PRINT_LOW("Processing extradata");
9069                        reconfig_event_sent = omx->handle_extradata(omxhdr);
9070 
9071                        if (omx->m_extradata_info.output_crop_updated) {
9072                            DEBUG_PRINT_LOW("Read FBD crop from output extra data");
9073                            vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
9074                            vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
9075                            vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
9076                            vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
9077                            vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
9078                            vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
9079                            memcpy(vdec_msg->msgdata.output_frame.misrinfo,
9080                                 omx->m_extradata_info.misr_info, sizeof(vdec_misrinfo));
9081                        } else {
9082                            DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
9083                            vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2];
9084                            vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3];
9085                            vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4];
9086                            vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
9087                            vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
9088                            vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
9089 
9090                            /* Copy these values back to OMX internal variables to make both handlign same*/
9091 
9092                            omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
9093                            omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top;
9094                            omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
9095                            omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
9096                            omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
9097                            omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
9098                        }
9099                    }
9100 
9101                    vdec_msg->msgdata.output_frame.bufferaddr =
9102                        omx_ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
9103 
9104                    DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
9105                            " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
9106                            omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
9107                            omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
9108                            vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
9109                            (unsigned int)vdec_msg->msgdata.output_frame.len,
9110                            vdec_msg->msgdata.output_frame.framesize.left,
9111                            vdec_msg->msgdata.output_frame.framesize.top,
9112                            vdec_msg->msgdata.output_frame.framesize.right,
9113                            vdec_msg->msgdata.output_frame.framesize.bottom);
9114 
9115                    /* Post event if resolution OR crop changed */
9116                    /* filled length will be changed if resolution changed */
9117                    /* Crop parameters can be changed even without resolution change */
9118                    if (omxhdr->nFilledLen
9119                        && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
9120                        || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
9121                        || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
9122                        || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
9123                        || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
9124                        || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
9125                        || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
9126 
9127                        DEBUG_PRINT_HIGH("Parameters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
9128                                omx->prev_n_filled_len,
9129                                omx->drv_ctx.video_resolution.frame_width,
9130                                omx->drv_ctx.video_resolution.frame_height,
9131                                omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
9132                                omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
9133                                omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
9134                                vdec_msg->msgdata.output_frame.picsize.frame_height,
9135                                vdec_msg->msgdata.output_frame.framesize.left,
9136                                vdec_msg->msgdata.output_frame.framesize.top,
9137                                vdec_msg->msgdata.output_frame.framesize.right,
9138                                vdec_msg->msgdata.output_frame.framesize.bottom);
9139 
9140                        memcpy(&omx->drv_ctx.frame_size,
9141                                &vdec_msg->msgdata.output_frame.framesize,
9142                                sizeof(struct vdec_framesize));
9143 
9144                        omx->drv_ctx.video_resolution.frame_width =
9145                                vdec_msg->msgdata.output_frame.picsize.frame_width;
9146                        omx->drv_ctx.video_resolution.frame_height =
9147                                vdec_msg->msgdata.output_frame.picsize.frame_height;
9148                        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
9149                            omx->drv_ctx.video_resolution.stride =
9150                                VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
9151                            omx->drv_ctx.video_resolution.scan_lines =
9152                                VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
9153                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
9154                            omx->drv_ctx.video_resolution.stride =
9155                                VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
9156                            omx->drv_ctx.video_resolution.scan_lines =
9157                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
9158                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
9159                            omx->drv_ctx.video_resolution.stride =
9160                                VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width);
9161                            omx->drv_ctx.video_resolution.scan_lines =
9162                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
9163                         }
9164                         else if(omx->drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
9165                            omx->drv_ctx.video_resolution.stride =
9166                                VENUS_Y_STRIDE(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_width);
9167                            omx->drv_ctx.video_resolution.scan_lines =
9168                                VENUS_Y_SCANLINES(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_height);
9169                         }
9170 
9171                        if(!reconfig_event_sent) {
9172                            omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
9173                                            OMX_IndexConfigCommonOutputCrop,
9174                                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9175                            reconfig_event_sent = true;
9176                        } else {
9177                            /* Update C2D with new resolution */
9178                            if (!omx->client_buffers.update_buffer_req()) {
9179                                DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
9180                            }
9181                        }
9182                    }
9183 
9184                    if (omxhdr->nFilledLen)
9185                        omx->prev_n_filled_len = omxhdr->nFilledLen;
9186 
9187                    if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer &&
9188                        vdec_msg->msgdata.output_frame.bufferaddr)
9189                        memcpy ( omxhdr->pBuffer, (void *)
9190                                ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
9191                                 (unsigned long)vdec_msg->msgdata.output_frame.offset),
9192                                vdec_msg->msgdata.output_frame.len);
9193 
9194                omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
9195                         OMX_COMPONENT_GENERATE_FBD);
9196 
9197             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
9198                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
9199                         OMX_COMPONENT_GENERATE_EOS_DONE);
9200             } else {
9201                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
9202                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
9203             }
9204             break;
9205         }
9206         case VDEC_MSG_EVT_CONFIG_CHANGED:
9207             DEBUG_PRINT_HIGH("Port settings changed");
9208             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
9209             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
9210             omx->isPortReconfigInsufficient = vdec_msg->msgdata.output_frame.flags;
9211             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
9212                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9213             break;
9214         default:
9215             break;
9216     }
9217     return rc;
9218 }
9219 
empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)9220 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
9221         OMX_HANDLETYPE hComp,
9222         OMX_BUFFERHEADERTYPE *buffer
9223         )
9224 {
9225     unsigned address,p2,id;
9226     DEBUG_PRINT_LOW("Empty this arbitrary");
9227 
9228     if (buffer == NULL) {
9229         return OMX_ErrorBadParameter;
9230     }
9231     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
9232     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
9233             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
9234 
9235     /* return zero length and not an EOS buffer */
9236     /* return buffer if input flush in progress */
9237     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
9238                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
9239         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
9240         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
9241         return OMX_ErrorNone;
9242     }
9243 
9244     if (psource_frame == NULL) {
9245         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
9246         psource_frame = buffer;
9247         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
9248         push_input_buffer (hComp);
9249     } else {
9250         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
9251         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
9252                     (unsigned)NULL)) {
9253             return OMX_ErrorBadParameter;
9254         }
9255     }
9256 
9257     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
9258         codec_config_flag = false;
9259     }
9260     return OMX_ErrorNone;
9261 }
9262 
push_input_buffer(OMX_HANDLETYPE hComp)9263 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
9264 {
9265     unsigned long address,p2,id;
9266     OMX_ERRORTYPE ret = OMX_ErrorNone;
9267 
9268     if (pdest_frame == NULL || psource_frame == NULL) {
9269         /*Check if we have a destination buffer*/
9270         if (pdest_frame == NULL) {
9271             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
9272             if (m_input_free_q.m_size) {
9273                 m_input_free_q.pop_entry(&address,&p2,&id);
9274                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
9275                 pdest_frame->nFilledLen = 0;
9276                 pdest_frame->nTimeStamp = LLONG_MAX;
9277                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
9278             }
9279         }
9280 
9281         /*Check if we have a destination buffer*/
9282         if (psource_frame == NULL) {
9283             DEBUG_PRINT_LOW("Get a source buffer from the queue");
9284             if (m_input_pending_q.m_size) {
9285                 m_input_pending_q.pop_entry(&address,&p2,&id);
9286                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9287                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9288                         psource_frame->nTimeStamp);
9289                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9290                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9291 
9292             }
9293         }
9294 
9295     }
9296 
9297     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
9298         switch (codec_type_parse) {
9299             case CODEC_TYPE_MPEG2:
9300                 ret =  push_input_sc_codec(hComp);
9301                 break;
9302             case CODEC_TYPE_H264:
9303                 ret = push_input_h264(hComp);
9304                 break;
9305             case CODEC_TYPE_HEVC:
9306                 ret = push_input_hevc(hComp);
9307                 break;
9308             default:
9309                 break;
9310         }
9311         if (ret != OMX_ErrorNone) {
9312             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
9313             omx_report_error ();
9314             break;
9315         }
9316     }
9317 
9318     return ret;
9319 }
9320 
push_input_sc_codec(OMX_HANDLETYPE hComp)9321 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
9322 {
9323     OMX_U32 partial_frame = 1;
9324     OMX_BOOL generate_ebd = OMX_TRUE;
9325     unsigned long address = 0, p2 = 0, id = 0;
9326 
9327     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
9328             psource_frame,psource_frame->nTimeStamp);
9329     if (m_frame_parser.parse_sc_frame(psource_frame,
9330                 pdest_frame,&partial_frame) == -1) {
9331         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9332         return OMX_ErrorBadParameter;
9333     }
9334 
9335     if (partial_frame == 0) {
9336         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
9337                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
9338 
9339 
9340         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
9341         /*First Parsed buffer will have only header Hence skip*/
9342         if (frame_count == 0) {
9343             frame_count++;
9344         } else {
9345             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9346             if (pdest_frame->nFilledLen) {
9347                 /*Push the frame to the Decoder*/
9348                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9349                     return OMX_ErrorBadParameter;
9350                 }
9351                 frame_count++;
9352                 pdest_frame = NULL;
9353 
9354                 if (m_input_free_q.m_size) {
9355                     m_input_free_q.pop_entry(&address,&p2,&id);
9356                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9357                     pdest_frame->nFilledLen = 0;
9358                 }
9359             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
9360                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
9361                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
9362                         (unsigned)NULL);
9363                 pdest_frame = NULL;
9364             }
9365         }
9366     } else {
9367         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
9368         /*Check if Destination Buffer is full*/
9369         if (pdest_frame->nAllocLen ==
9370                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
9371             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
9372             return OMX_ErrorStreamCorrupt;
9373         }
9374     }
9375 
9376     if (psource_frame->nFilledLen == 0) {
9377         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9378             if (pdest_frame) {
9379                 pdest_frame->nFlags |= psource_frame->nFlags;
9380                 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
9381                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
9382                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9383                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9384                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
9385                 /*Push the frame to the Decoder*/
9386                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9387                     return OMX_ErrorBadParameter;
9388                 }
9389                 frame_count++;
9390                 pdest_frame = NULL;
9391             } else {
9392                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
9393                 generate_ebd = OMX_FALSE;
9394             }
9395         }
9396         if (generate_ebd) {
9397             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
9398             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9399             psource_frame = NULL;
9400 
9401             if (m_input_pending_q.m_size) {
9402                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9403                 m_input_pending_q.pop_entry(&address,&p2,&id);
9404                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9405                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9406                         psource_frame->nTimeStamp);
9407                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9408                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9409             }
9410         }
9411     }
9412     return OMX_ErrorNone;
9413 }
9414 
push_input_h264(OMX_HANDLETYPE hComp)9415 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
9416 {
9417     OMX_U32 partial_frame = 1;
9418     unsigned long address = 0, p2 = 0, id = 0;
9419     OMX_BOOL isNewFrame = OMX_FALSE;
9420     OMX_BOOL generate_ebd = OMX_TRUE;
9421 
9422     if (h264_scratch.pBuffer == NULL) {
9423         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
9424         return OMX_ErrorBadParameter;
9425     }
9426     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
9427             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
9428     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
9429     if (h264_scratch.nFilledLen && look_ahead_nal) {
9430         look_ahead_nal = false;
9431         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9432                 h264_scratch.nFilledLen) {
9433             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9434                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
9435             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9436             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
9437             h264_scratch.nFilledLen = 0;
9438         } else {
9439             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
9440             return OMX_ErrorBadParameter;
9441         }
9442     }
9443 
9444     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
9445        in EOS flag getting associated with the destination
9446     */
9447     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
9448             pdest_frame->nFilledLen) {
9449         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
9450         generate_ebd = OMX_FALSE;
9451     }
9452 
9453     if (nal_length == 0) {
9454         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
9455         if (m_frame_parser.parse_sc_frame(psource_frame,
9456                     &h264_scratch,&partial_frame) == -1) {
9457             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9458             return OMX_ErrorBadParameter;
9459         }
9460     } else {
9461         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
9462         if (m_frame_parser.parse_h264_nallength(psource_frame,
9463                     &h264_scratch,&partial_frame) == -1) {
9464             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9465             return OMX_ErrorBadParameter;
9466         }
9467     }
9468 
9469     if (partial_frame == 0) {
9470         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9471             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9472             nal_count++;
9473             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9474             h264_scratch.nFlags = psource_frame->nFlags;
9475         } else {
9476             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
9477             if (h264_scratch.nFilledLen) {
9478                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
9479                         NALU_TYPE_SPS);
9480 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9481                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
9482                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9483                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
9484                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9485                     // If timeinfo is present frame info from SEI is already processed
9486                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9487                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
9488 #endif
9489                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9490                 nal_count++;
9491                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
9492                     pdest_frame->nTimeStamp = h264_last_au_ts;
9493                     pdest_frame->nFlags = h264_last_au_flags;
9494 #ifdef PANSCAN_HDLR
9495                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9496                         h264_parser->update_panscan_data(h264_last_au_ts);
9497 #endif
9498                 }
9499                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
9500                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
9501                     h264_last_au_ts = h264_scratch.nTimeStamp;
9502                     h264_last_au_flags = h264_scratch.nFlags;
9503 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9504                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9505                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
9506                         if (!VALID_TS(h264_last_au_ts))
9507                             h264_last_au_ts = ts_in_sei;
9508                     }
9509 #endif
9510                 } else
9511                     h264_last_au_ts = LLONG_MAX;
9512             }
9513 
9514             if (!isNewFrame) {
9515                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9516                         h264_scratch.nFilledLen) {
9517                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
9518                             (unsigned int)h264_scratch.nFilledLen);
9519                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9520                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
9521                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9522                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
9523                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
9524                     h264_scratch.nFilledLen = 0;
9525                 } else {
9526                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
9527                     return OMX_ErrorBadParameter;
9528                 }
9529             } else if(h264_scratch.nFilledLen) {
9530                 look_ahead_nal = true;
9531                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
9532                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9533                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9534                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
9535 
9536                 if (pdest_frame->nFilledLen == 0) {
9537                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
9538                     look_ahead_nal = false;
9539                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9540                             h264_scratch.nFilledLen) {
9541                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9542                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9543                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9544                         h264_scratch.nFilledLen = 0;
9545                     } else {
9546                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
9547                         return OMX_ErrorBadParameter;
9548                     }
9549                 } else {
9550                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9551                         DEBUG_PRINT_LOW("Reset the EOS Flag");
9552                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9553                     }
9554                     /*Push the frame to the Decoder*/
9555                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9556                         return OMX_ErrorBadParameter;
9557                     }
9558                     //frame_count++;
9559                     pdest_frame = NULL;
9560                     if (m_input_free_q.m_size) {
9561                         m_input_free_q.pop_entry(&address,&p2,&id);
9562                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9563                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
9564                         pdest_frame->nFilledLen = 0;
9565                         pdest_frame->nFlags = 0;
9566                         pdest_frame->nTimeStamp = LLONG_MAX;
9567                     }
9568                 }
9569             }
9570         }
9571     } else {
9572         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
9573         /*Check if Destination Buffer is full*/
9574         if (h264_scratch.nAllocLen ==
9575                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9576             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9577             return OMX_ErrorStreamCorrupt;
9578         }
9579     }
9580 
9581     if (!psource_frame->nFilledLen) {
9582         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
9583 
9584         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9585             if (pdest_frame) {
9586                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9587                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9588                         h264_scratch.nFilledLen) {
9589                     if(pdest_frame->nFilledLen == 0) {
9590                         /* No residual frame from before, send whatever
9591                          * we have left */
9592                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9593                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
9594                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9595                         h264_scratch.nFilledLen = 0;
9596                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9597                     } else {
9598                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9599                         if(!isNewFrame) {
9600                             /* Have a residual frame, but we know that the
9601                              * AU in this frame is belonging to whatever
9602                              * frame we had left over.  So append it */
9603                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9604                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
9605                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9606                              h264_scratch.nFilledLen = 0;
9607                              if (h264_last_au_ts != LLONG_MAX)
9608                                  pdest_frame->nTimeStamp = h264_last_au_ts;
9609                         } else {
9610                             /* Completely new frame, let's just push what
9611                              * we have now.  The resulting EBD would trigger
9612                              * another push */
9613                             generate_ebd = OMX_FALSE;
9614                             pdest_frame->nTimeStamp = h264_last_au_ts;
9615                             h264_last_au_ts = h264_scratch.nTimeStamp;
9616                         }
9617                     }
9618                 } else {
9619                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
9620                     return OMX_ErrorBadParameter;
9621                 }
9622 
9623                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
9624                 if(generate_ebd == OMX_TRUE) {
9625                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9626                 }
9627 
9628                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
9629                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9630                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
9631 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9632                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9633                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
9634                     if (!VALID_TS(pdest_frame->nTimeStamp))
9635                         pdest_frame->nTimeStamp = ts_in_sei;
9636                 }
9637 #endif
9638                 /*Push the frame to the Decoder*/
9639                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9640                     return OMX_ErrorBadParameter;
9641                 }
9642                 frame_count++;
9643                 pdest_frame = NULL;
9644             } else {
9645                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9646                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9647                 generate_ebd = OMX_FALSE;
9648             }
9649         }
9650     }
9651     if (generate_ebd && !psource_frame->nFilledLen) {
9652         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9653         psource_frame = NULL;
9654         if (m_input_pending_q.m_size) {
9655             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9656             m_input_pending_q.pop_entry(&address,&p2,&id);
9657             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9658             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
9659                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9660         }
9661     }
9662     return OMX_ErrorNone;
9663 }
9664 
copy_buffer(OMX_BUFFERHEADERTYPE * pDst,OMX_BUFFERHEADERTYPE * pSrc)9665 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
9666 {
9667     OMX_ERRORTYPE rc = OMX_ErrorNone;
9668     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
9669         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
9670         if (pDst->nTimeStamp == LLONG_MAX) {
9671             pDst->nTimeStamp = pSrc->nTimeStamp;
9672             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
9673         }
9674         pDst->nFilledLen += pSrc->nFilledLen;
9675         pSrc->nFilledLen = 0;
9676     } else {
9677         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
9678         rc = OMX_ErrorBadParameter;
9679     }
9680     return rc;
9681 }
9682 
push_input_hevc(OMX_HANDLETYPE hComp)9683 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
9684 {
9685     OMX_U32 partial_frame = 1;
9686     unsigned long address,p2,id;
9687     OMX_BOOL isNewFrame = OMX_FALSE;
9688     OMX_BOOL generate_ebd = OMX_TRUE;
9689     OMX_ERRORTYPE rc = OMX_ErrorNone;
9690     if (h264_scratch.pBuffer == NULL) {
9691         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
9692         return OMX_ErrorBadParameter;
9693     }
9694 
9695     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
9696             pdest_frame nFilledLen %u nTimeStamp %lld",
9697             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9698 
9699     if (h264_scratch.nFilledLen && look_ahead_nal) {
9700         look_ahead_nal = false;
9701         rc = copy_buffer(pdest_frame, &h264_scratch);
9702         if (rc != OMX_ErrorNone) {
9703             return rc;
9704         }
9705     }
9706 
9707     if (nal_length == 0) {
9708         if (m_frame_parser.parse_sc_frame(psource_frame,
9709                     &h264_scratch,&partial_frame) == -1) {
9710             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9711             return OMX_ErrorBadParameter;
9712         }
9713     } else {
9714         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
9715         if (m_frame_parser.parse_h264_nallength(psource_frame,
9716                     &h264_scratch,&partial_frame) == -1) {
9717             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9718             return OMX_ErrorBadParameter;
9719         }
9720     }
9721 
9722     if (partial_frame == 0) {
9723         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9724             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9725             nal_count++;
9726             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9727             h264_scratch.nFlags = psource_frame->nFlags;
9728         } else {
9729             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
9730             if (h264_scratch.nFilledLen) {
9731                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
9732                 nal_count++;
9733             }
9734 
9735             if (!isNewFrame) {
9736                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
9737                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
9738                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
9739                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9740                 rc = copy_buffer(pdest_frame, &h264_scratch);
9741                 if (rc != OMX_ErrorNone) {
9742                     return rc;
9743                 }
9744             } else {
9745                 look_ahead_nal = true;
9746                 if (pdest_frame->nFilledLen == 0) {
9747                     look_ahead_nal = false;
9748                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
9749                     rc = copy_buffer(pdest_frame, &h264_scratch);
9750                     if (rc != OMX_ErrorNone) {
9751                         return OMX_ErrorBadParameter;
9752                     }
9753                 } else {
9754                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9755                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9756                     }
9757                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
9758                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
9759                             nFilledLen %u nTimeStamp %lld",
9760                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
9761                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
9762                             h264_scratch.nTimeStamp);
9763                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9764                         return OMX_ErrorBadParameter;
9765                     }
9766                     pdest_frame = NULL;
9767                     if (m_input_free_q.m_size) {
9768                         m_input_free_q.pop_entry(&address, &p2, &id);
9769                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9770                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
9771                         pdest_frame->nFilledLen = 0;
9772                         pdest_frame->nFlags = 0;
9773                         pdest_frame->nTimeStamp = LLONG_MAX;
9774                     }
9775                 }
9776             }
9777         }
9778     } else {
9779         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
9780                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
9781                 nFilledLen %u nTimeStamp %lld",
9782                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
9783                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
9784                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
9785 
9786         if (h264_scratch.nAllocLen ==
9787                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9788             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9789             return OMX_ErrorStreamCorrupt;
9790         }
9791     }
9792 
9793     if (!psource_frame->nFilledLen) {
9794         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
9795         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9796             if (pdest_frame) {
9797                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9798                 rc = copy_buffer(pdest_frame, &h264_scratch);
9799                 if ( rc != OMX_ErrorNone ) {
9800                     return rc;
9801                 }
9802                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9803                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9804                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
9805                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9806                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9807                     return OMX_ErrorBadParameter;
9808                 }
9809                 frame_count++;
9810                 pdest_frame = NULL;
9811             } else {
9812                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9813                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9814                 generate_ebd = OMX_FALSE;
9815             }
9816         }
9817     }
9818 
9819     if (generate_ebd && !psource_frame->nFilledLen) {
9820         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
9821         psource_frame = NULL;
9822         if (m_input_pending_q.m_size) {
9823             m_input_pending_q.pop_entry(&address, &p2, &id);
9824             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9825             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
9826                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
9827         }
9828     }
9829     return OMX_ErrorNone;
9830 }
9831 
9832 #ifdef USE_GBM
alloc_map_gbm_memory(OMX_U32 w,OMX_U32 h,int dev_fd,struct vdec_gbm * op_buf_gbm_info,int flag)9833 bool omx_vdec::alloc_map_gbm_memory(OMX_U32 w,OMX_U32 h,int dev_fd,
9834                  struct vdec_gbm *op_buf_gbm_info, int flag)
9835 {
9836 
9837     uint32 flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
9838     struct gbm_device *gbm = NULL;
9839     struct gbm_bo *bo = NULL;
9840     int bo_fd = -1, meta_fd = -1;
9841     if (!op_buf_gbm_info || dev_fd < 0 ) {
9842         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9843         return FALSE;
9844     }
9845 
9846     gbm = gbm_create_device(dev_fd);
9847     if (gbm == NULL) {
9848        DEBUG_PRINT_ERROR("create gbm device failed");
9849        return FALSE;
9850     } else {
9851        DEBUG_PRINT_LOW( "Successfully created gbm device");
9852     }
9853     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC)
9854        flags |= GBM_BO_USAGE_UBWC_ALIGNED_QTI;
9855 
9856     DEBUG_PRINT_LOW("create NV12 gbm_bo with width=%d, height=%d", w, h);
9857     bo = gbm_bo_create(gbm, w, h,GBM_FORMAT_NV12,
9858               flags);
9859 
9860     if (bo == NULL) {
9861       DEBUG_PRINT_ERROR("Create bo failed");
9862       gbm_device_destroy(gbm);
9863       return FALSE;
9864     }
9865 
9866     bo_fd = gbm_bo_get_fd(bo);
9867     if (bo_fd < 0) {
9868       DEBUG_PRINT_ERROR("Get bo fd failed");
9869       gbm_bo_destroy(bo);
9870       gbm_device_destroy(gbm);
9871       return FALSE;
9872     }
9873 
9874     gbm_perform(GBM_PERFORM_GET_METADATA_ION_FD, bo, &meta_fd);
9875     if (meta_fd < 0) {
9876       DEBUG_PRINT_ERROR("Get bo meta fd failed");
9877       gbm_bo_destroy(bo);
9878       gbm_device_destroy(gbm);
9879       return FALSE;
9880     }
9881     op_buf_gbm_info->gbm = gbm;
9882     op_buf_gbm_info->bo = bo;
9883     op_buf_gbm_info->bo_fd = bo_fd;
9884     op_buf_gbm_info->meta_fd = meta_fd;
9885 
9886     DEBUG_PRINT_LOW("allocate gbm bo fd meta fd  %p %d %d",bo,bo_fd,meta_fd);
9887     return TRUE;
9888 }
9889 
free_gbm_memory(struct vdec_gbm * buf_gbm_info)9890 void omx_vdec::free_gbm_memory(struct vdec_gbm *buf_gbm_info)
9891 {
9892     if(!buf_gbm_info) {
9893       DEBUG_PRINT_ERROR(" GBM: free called with invalid fd/allocdata");
9894       return;
9895     }
9896     DEBUG_PRINT_LOW("free gbm bo fd meta fd  %p %d %d",
9897            buf_gbm_info->bo,buf_gbm_info->bo_fd,buf_gbm_info->meta_fd);
9898 
9899     if (buf_gbm_info->bo)
9900        gbm_bo_destroy(buf_gbm_info->bo);
9901     buf_gbm_info->bo = NULL;
9902 
9903     if (buf_gbm_info->gbm)
9904        gbm_device_destroy(buf_gbm_info->gbm);
9905     buf_gbm_info->gbm = NULL;
9906 
9907     buf_gbm_info->bo_fd = -1;
9908     buf_gbm_info->meta_fd = -1;
9909 }
9910 #endif
9911 #ifndef USE_ION
align_pmem_buffers(int pmem_fd,OMX_U32 buffer_size,OMX_U32 alignment)9912 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
9913         OMX_U32 alignment)
9914 {
9915     struct pmem_allocation allocation;
9916     allocation.size = buffer_size;
9917     allocation.align = clip2(alignment);
9918     if (allocation.align < 4096) {
9919         allocation.align = 4096;
9920     }
9921     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
9922         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
9923                 allocation.align, allocation.size);
9924         return false;
9925     }
9926     return true;
9927 }
9928 #endif
9929 #ifdef USE_ION
alloc_map_ion_memory(OMX_U32 buffer_size,vdec_ion * ion_info,int flag)9930 bool omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, vdec_ion *ion_info, int flag)
9931 
9932 {
9933     int rc = -EINVAL;
9934     int ion_dev_flag;
9935     struct vdec_ion ion_buf_info;
9936 
9937     if (!ion_info || buffer_size <= 0) {
9938         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9939         return false;
9940     }
9941 
9942     ion_info->dev_fd = ion_open();
9943     if (ion_info->dev_fd < 0) {
9944         DEBUG_PRINT_ERROR("opening ion device failed with ion_fd = %d", ion_info->dev_fd);
9945         return false;
9946     }
9947 
9948 #ifdef HYPERVISOR
9949     flag &= ~ION_FLAG_CACHED;
9950 #endif
9951     ion_info->alloc_data.flags = flag;
9952     ion_info->alloc_data.len = buffer_size;
9953 
9954     ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
9955     if (secure_mode && (ion_info->alloc_data.flags & ION_FLAG_SECURE)) {
9956 #ifdef HYPERVISOR
9957         ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
9958 #else
9959         ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
9960 #endif
9961     }
9962 
9963     /* Use secure display cma heap for obvious reasons. */
9964     if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
9965         ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
9966     }
9967 
9968     rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
9969                       ion_info->alloc_data.heap_id_mask, ion_info->alloc_data.flags,
9970                       &ion_info->data_fd);
9971 
9972     if (rc || ion_info->data_fd < 0) {
9973         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
9974         ion_close(ion_info->dev_fd);
9975         ion_info->data_fd = -1;
9976         ion_info->dev_fd = -1;
9977         return false;
9978     }
9979 
9980     DEBUG_PRINT_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
9981                      ion_info->dev_fd, ion_info->data_fd, (unsigned int)ion_info->alloc_data.len,
9982                      (unsigned int)ion_info->alloc_data.flags,
9983                      (unsigned int)ion_info->alloc_data.heap_id_mask);
9984 
9985     return true;
9986 }
9987 
free_ion_memory(struct vdec_ion * buf_ion_info)9988 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
9989 {
9990 
9991     if (!buf_ion_info) {
9992         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
9993         return;
9994     }
9995     DEBUG_PRINT_HIGH("Free ion memory: mmap fd %d ion_dev fd %d len %d flags %#x mask %#x",
9996         buf_ion_info->data_fd, buf_ion_info->dev_fd,
9997         (unsigned int)buf_ion_info->alloc_data.len,
9998         (unsigned int)buf_ion_info->alloc_data.flags,
9999         (unsigned int)buf_ion_info->alloc_data.heap_id_mask);
10000 
10001     if (buf_ion_info->data_fd >= 0) {
10002         close(buf_ion_info->data_fd);
10003         buf_ion_info->data_fd = -1;
10004     }
10005     if (buf_ion_info->dev_fd >= 0) {
10006         ion_close(buf_ion_info->dev_fd);
10007         buf_ion_info->dev_fd = -1;
10008     }
10009 }
10010 
do_cache_operations(int fd)10011 void omx_vdec::do_cache_operations(int fd)
10012 {
10013     if (fd < 0)
10014         return;
10015 
10016     struct dma_buf_sync dma_buf_sync_data[2];
10017     dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
10018     dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
10019 
10020     for(unsigned int i=0; i<2; i++) {
10021         int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
10022         if (rc < 0) {
10023             DEBUG_PRINT_ERROR("Failed DMA_BUF_IOCTL_SYNC %s fd : %d", i==0?"start":"end", fd);
10024             return;
10025         }
10026     }
10027 }
10028 
10029 #endif
free_output_buffer_header(bool intermediate)10030 void omx_vdec::free_output_buffer_header(bool intermediate)
10031 {
10032     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
10033     output_use_buffer = false;
10034     ouput_egl_buffers = false;
10035 
10036     OMX_BUFFERHEADERTYPE  **omx_base_address =
10037         intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
10038     vdec_bufferpayload **omx_ptr_outputbuffer =
10039         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
10040     vdec_output_frameinfo **omx_ptr_respbuffer =
10041         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
10042     vdec_ion **omx_op_buf_ion_info =
10043         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
10044 #ifdef USE_GBM
10045     vdec_gbm **omx_op_buf_gbm_info =
10046         intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
10047 #endif
10048 
10049     if (*omx_base_address) {
10050         free (*omx_base_address);
10051         *omx_base_address = NULL;
10052     }
10053 
10054     if (m_platform_list) {
10055         free(m_platform_list);
10056         m_platform_list = NULL;
10057     }
10058 
10059     if (*omx_ptr_respbuffer) {
10060         free (*omx_ptr_respbuffer);
10061         *omx_ptr_respbuffer = NULL;
10062     }
10063     if (*omx_ptr_outputbuffer) {
10064         free (*omx_ptr_outputbuffer);
10065         *omx_ptr_outputbuffer = NULL;
10066     }
10067 #ifdef USE_GBM
10068     if (*omx_op_buf_gbm_info) {
10069         DEBUG_PRINT_LOW("Free o/p gbm context");
10070         free(*omx_op_buf_gbm_info);
10071         *omx_op_buf_gbm_info = NULL;
10072     }
10073     if (drv_ctx.gbm_device_fd >= 0) {
10074        DEBUG_PRINT_LOW("Close gbm device");
10075        close(drv_ctx.gbm_device_fd);
10076        drv_ctx.gbm_device_fd = -1;
10077     }
10078 
10079 #elif defined USE_ION
10080     if (*omx_op_buf_ion_info) {
10081         DEBUG_PRINT_LOW("Free o/p ion context");
10082         free(*omx_op_buf_ion_info);
10083         *omx_op_buf_ion_info = NULL;
10084     }
10085 #endif
10086     if (intermediate == false && client_buffers.is_color_conversion_enabled()) {
10087         free_output_buffer_header(true);
10088     }
10089 }
10090 
free_input_buffer_header()10091 void omx_vdec::free_input_buffer_header()
10092 {
10093     input_use_buffer = false;
10094     if (arbitrary_bytes) {
10095         if (m_inp_heap_ptr) {
10096             DEBUG_PRINT_LOW("Free input Heap Pointer");
10097             free (m_inp_heap_ptr);
10098             m_inp_heap_ptr = NULL;
10099         }
10100 
10101         if (m_phdr_pmem_ptr) {
10102             DEBUG_PRINT_LOW("Free input pmem header Pointer");
10103             free (m_phdr_pmem_ptr);
10104             m_phdr_pmem_ptr = NULL;
10105         }
10106     }
10107     if (m_inp_mem_ptr) {
10108         DEBUG_PRINT_LOW("Free input pmem Pointer area");
10109         free (m_inp_mem_ptr);
10110         m_inp_mem_ptr = NULL;
10111     }
10112     /* We just freed all the buffer headers, every thing in m_input_free_q,
10113      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
10114     while (m_input_free_q.m_size) {
10115         unsigned long address, p2, id;
10116         m_input_free_q.pop_entry(&address, &p2, &id);
10117     }
10118     while (m_input_pending_q.m_size) {
10119         unsigned long address, p2, id;
10120         m_input_pending_q.pop_entry(&address, &p2, &id);
10121     }
10122     pdest_frame = NULL;
10123     psource_frame = NULL;
10124     if (drv_ctx.ptr_inputbuffer) {
10125         DEBUG_PRINT_LOW("Free Driver Context pointer");
10126         free (drv_ctx.ptr_inputbuffer);
10127         drv_ctx.ptr_inputbuffer = NULL;
10128     }
10129 #ifdef USE_ION
10130     if (drv_ctx.ip_buf_ion_info) {
10131         DEBUG_PRINT_LOW("Free ion context");
10132         free(drv_ctx.ip_buf_ion_info);
10133         drv_ctx.ip_buf_ion_info = NULL;
10134     }
10135 #endif
10136 }
10137 
free_output_extradata_buffer_header()10138 void omx_vdec::free_output_extradata_buffer_header() {
10139     client_extradata = false;
10140     if (m_client_output_extradata_mem_ptr) {
10141         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
10142         free(m_client_output_extradata_mem_ptr);
10143         m_client_output_extradata_mem_ptr = NULL;
10144     }
10145 }
10146 
stream_off(OMX_U32 port)10147 int omx_vdec::stream_off(OMX_U32 port)
10148 {
10149     enum v4l2_buf_type btype;
10150     int rc = 0;
10151     enum v4l2_ports v4l2_port = OUTPUT_PORT;
10152     struct v4l2_requestbuffers bufreq;
10153 
10154     if (port == OMX_CORE_INPUT_PORT_INDEX) {
10155         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10156         v4l2_port = OUTPUT_PORT;
10157     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10158         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10159         v4l2_port = CAPTURE_PORT;
10160     } else if (port == OMX_ALL) {
10161         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
10162         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
10163 
10164         if (!rc_input)
10165             return rc_input;
10166         else
10167             return rc_output;
10168     }
10169 
10170     if (!streaming[v4l2_port]) {
10171         // already streamed off, warn and move on
10172         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
10173                 " which is already streamed off", v4l2_port);
10174         return 0;
10175     }
10176 
10177     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
10178 
10179     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
10180     if (rc) {
10181         /*TODO: How to handle this case */
10182         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
10183     } else {
10184         streaming[v4l2_port] = false;
10185     }
10186 
10187     if (port == OMX_CORE_INPUT_PORT_INDEX) {
10188         bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10189     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10190         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10191     }
10192 
10193     bufreq.memory = V4L2_MEMORY_USERPTR;
10194     bufreq.count = 0;
10195     rc = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10196     if (rc) {
10197         DEBUG_PRINT_ERROR("Failed to release buffers on %d Port", v4l2_port);
10198     }
10199     return rc;
10200 }
10201 
get_buffer_req(vdec_allocatorproperty * buffer_prop)10202 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
10203 {
10204     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10205     struct v4l2_control control;
10206     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
10207     unsigned int final_extra_data_size = 0;
10208     struct v4l2_format fmt;
10209     int ret = 0;
10210     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10211             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10212 
10213     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10214         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10215         fmt.fmt.pix_mp.pixelformat = output_capability;
10216         control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
10217     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10218         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10219         fmt.fmt.pix_mp.pixelformat = capture_capability;
10220         control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
10221     } else {
10222         eRet = OMX_ErrorBadParameter;
10223     }
10224     if (eRet == OMX_ErrorNone) {
10225         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control);
10226     }
10227     if (ret) {
10228         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10229         /*TODO: How to handle this case */
10230         eRet = OMX_ErrorInsufficientResources;
10231         return eRet;
10232     }
10233     buffer_prop->actualcount = buffer_prop->mincount = control.value;
10234     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10235             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10236 
10237     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10238 
10239     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
10240         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
10241     DEBUG_PRINT_HIGH("Buffer Size = %d, type = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.type);
10242 
10243     if (ret) {
10244         /*TODO: How to handle this case */
10245         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10246         eRet = OMX_ErrorInsufficientResources;
10247     } else {
10248         int extra_idx = 0;
10249 
10250         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10251         buf_size = buffer_prop->buffer_size;
10252         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
10253         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
10254             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
10255         } else if (extra_idx >= VIDEO_MAX_PLANES) {
10256             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
10257             return OMX_ErrorBadParameter;
10258         }
10259 
10260         default_extra_data_size = VENUS_EXTRADATA_SIZE(
10261                 drv_ctx.video_resolution.frame_height,
10262                 drv_ctx.video_resolution.frame_width);
10263         final_extra_data_size = extra_data_size > default_extra_data_size ?
10264             extra_data_size : default_extra_data_size;
10265 
10266         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
10267             (~(buffer_prop->alignment - 1));
10268 
10269         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
10270         drv_ctx.extradata_info.count = buffer_prop->actualcount;
10271         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
10272         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10273         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
10274                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
10275         if (extra_data_size)
10276             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
10277                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
10278 
10279         if (in_reconfig) // BufReq will be set to driver when port is disabled
10280             buffer_prop->buffer_size = buf_size;
10281         else if (buf_size != buffer_prop->buffer_size) {
10282             buffer_prop->buffer_size = buf_size;
10283             eRet = set_buffer_req(buffer_prop);
10284         }
10285     }
10286     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
10287             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10288     return eRet;
10289 }
10290 
set_buffer_req(vdec_allocatorproperty * buffer_prop)10291 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
10292 {
10293     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10294     unsigned buf_size = 0;
10295     struct v4l2_format fmt, c_fmt;
10296     struct v4l2_requestbuffers bufreq;
10297     int ret = 0;
10298     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
10299             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10300     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10301     if (buf_size != buffer_prop->buffer_size) {
10302         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
10303                 (unsigned int)buffer_prop->buffer_size, buf_size);
10304         eRet = OMX_ErrorBadParameter;
10305     } else {
10306         memset(&fmt, 0x0, sizeof(struct v4l2_format));
10307         memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
10308         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
10309         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
10310         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10311 
10312         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10313             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10314             fmt.fmt.pix_mp.pixelformat = output_capability;
10315             DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10316                 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10317                 fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.pixelformat);
10318             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10319         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10320             c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10321             c_fmt.fmt.pix_mp.pixelformat = capture_capability;
10322             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
10323             c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10324             DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10325                 c_fmt.type, c_fmt.fmt.pix_mp.width, c_fmt.fmt.pix_mp.height,
10326                 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage, c_fmt.fmt.pix_mp.pixelformat);
10327             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
10328         } else {
10329             eRet = OMX_ErrorBadParameter;
10330         }
10331         if (ret) {
10332             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
10333             eRet = OMX_ErrorInsufficientResources;
10334         }
10335 
10336         bufreq.memory = V4L2_MEMORY_USERPTR;
10337         bufreq.count = buffer_prop->actualcount;
10338         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10339             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10340         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10341             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10342         } else {
10343             eRet = OMX_ErrorBadParameter;
10344         }
10345 
10346         if (eRet == OMX_ErrorNone) {
10347             DEBUG_PRINT_LOW("REQBUFS: type %d count %d", bufreq.type, bufreq.count);
10348             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10349         }
10350 
10351         if (ret) {
10352             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
10353             /*TODO: How to handle this case */
10354             eRet = OMX_ErrorInsufficientResources;
10355         } else if (bufreq.count < buffer_prop->actualcount) {
10356             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
10357                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
10358                     buffer_prop->actualcount, bufreq.count);
10359             eRet = OMX_ErrorInsufficientResources;
10360         } else {
10361             if (!client_buffers.update_buffer_req()) {
10362                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
10363                 eRet = OMX_ErrorInsufficientResources;
10364             }
10365         }
10366     }
10367     return eRet;
10368 }
10369 
update_picture_resolution()10370 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
10371 {
10372     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10373     return eRet;
10374 }
10375 
update_portdef(OMX_PARAM_PORTDEFINITIONTYPE * portDefn)10376 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
10377 {
10378     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10379     struct v4l2_format fmt;
10380     if (!portDefn) {
10381         DEBUG_PRINT_ERROR("update_portdef: invalid params");
10382         return OMX_ErrorBadParameter;
10383     }
10384     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
10385     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
10386     portDefn->eDomain    = OMX_PortDomainVideo;
10387     memset(&fmt, 0x0, sizeof(struct v4l2_format));
10388     if (0 == portDefn->nPortIndex) {
10389         int ret = 0;
10390         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10391         fmt.fmt.pix_mp.pixelformat = output_capability;
10392         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10393         if (ret) {
10394             DEBUG_PRINT_ERROR("Get Resolution failed");
10395             return OMX_ErrorHardware;
10396         }
10397         drv_ctx.ip_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10398         portDefn->eDir =  OMX_DirInput;
10399         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
10400         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
10401         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
10402         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10403         portDefn->format.video.eCompressionFormat = eCompressionFormat;
10404         //for input port, always report the fps value set by client,
10405         //to distinguish whether client got valid fps from parser.
10406         portDefn->format.video.xFramerate = m_fps_received;
10407         portDefn->bEnabled   = m_inp_bEnabled;
10408         portDefn->bPopulated = m_inp_bPopulated;
10409     } else if (1 == portDefn->nPortIndex) {
10410         unsigned int buf_size = 0;
10411         int ret = 0;
10412        if (!is_down_scalar_enabled) {
10413            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10414            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10415            fmt.fmt.pix_mp.pixelformat = capture_capability;
10416            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10417            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10418        }
10419 
10420        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10421        fmt.fmt.pix_mp.pixelformat = capture_capability;
10422        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10423        if (ret) {
10424            DEBUG_PRINT_ERROR("Get Resolution failed");
10425            return OMX_ErrorHardware;
10426        }
10427        drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10428        if (!client_buffers.update_buffer_req()) {
10429            DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
10430            return OMX_ErrorHardware;
10431        }
10432 
10433         if (!client_buffers.get_buffer_req(buf_size)) {
10434             DEBUG_PRINT_ERROR("update buffer requirements");
10435             return OMX_ErrorHardware;
10436         }
10437         portDefn->nBufferSize = buf_size;
10438         portDefn->eDir =  OMX_DirOutput;
10439         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
10440         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
10441         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10442         if (drv_ctx.frame_rate.fps_denominator > 0)
10443             portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
10444                 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
10445         else {
10446             DEBUG_PRINT_ERROR("Error: Divide by zero");
10447             return OMX_ErrorBadParameter;
10448         }
10449         portDefn->bEnabled   = m_out_bEnabled;
10450         portDefn->bPopulated = m_out_bPopulated;
10451         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
10452             DEBUG_PRINT_ERROR("Error in getting color format");
10453             return OMX_ErrorHardware;
10454         }
10455         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10456         fmt.fmt.pix_mp.pixelformat = capture_capability;
10457     } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
10458         portDefn->nBufferSize = m_client_out_extradata_info.getSize();
10459         portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10460         portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10461         portDefn->eDir =  OMX_DirOutput;
10462         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
10463         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
10464         portDefn->format.video.nStride  = drv_ctx.video_resolution.stride;
10465         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10466         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10467         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10468         DEBUG_PRINT_LOW(" get_parameter: Port idx %d nBufSize %u nBufCnt %u",
10469                 (int)portDefn->nPortIndex,
10470                 (unsigned int)portDefn->nBufferSize,
10471                 (unsigned int)portDefn->nBufferCountActual);
10472         return eRet;
10473     } else {
10474         portDefn->eDir = OMX_DirMax;
10475         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
10476                 (int)portDefn->nPortIndex);
10477         eRet = OMX_ErrorBadPortIndex;
10478     }
10479     if (in_reconfig) {
10480         m_extradata_info.output_crop_rect.nLeft = 0;
10481         m_extradata_info.output_crop_rect.nTop = 0;
10482         m_extradata_info.output_crop_rect.nWidth = fmt.fmt.pix_mp.width;
10483         m_extradata_info.output_crop_rect.nHeight = fmt.fmt.pix_mp.height;
10484     }
10485     update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10486         fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
10487 
10488     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
10489     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
10490     portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
10491     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10492 
10493     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
10494        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
10495            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
10496            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
10497     }
10498     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
10499             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
10500             (unsigned int)portDefn->nPortIndex,
10501             (unsigned int)portDefn->format.video.nFrameWidth,
10502             (unsigned int)portDefn->format.video.nFrameHeight,
10503             (int)portDefn->format.video.nStride,
10504             (unsigned int)portDefn->format.video.nSliceHeight,
10505             (unsigned int)portDefn->format.video.eColorFormat,
10506             (unsigned int)portDefn->nBufferSize,
10507             (unsigned int)portDefn->nBufferCountActual);
10508 
10509     return eRet;
10510 }
10511 
allocate_output_headers(bool intermediate)10512 OMX_ERRORTYPE omx_vdec::allocate_output_headers(bool intermediate)
10513 {
10514     OMX_ERRORTYPE eRet = OMX_ErrorNone;
10515     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
10516     unsigned i = 0;
10517 
10518     OMX_BUFFERHEADERTYPE  **omx_base_address =
10519                       intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
10520     vdec_bufferpayload **omx_ptr_outputbuffer =
10521         intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
10522     vdec_output_frameinfo **omx_ptr_respbuffer =
10523         intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
10524     vdec_ion **omx_op_buf_ion_info =
10525         intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
10526 
10527     if (!*omx_base_address) {
10528         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation, Cnt %d Sz %d",
10529             drv_ctx.op_buf.actualcount, (unsigned int)drv_ctx.op_buf.buffer_size);
10530         int nBufHdrSize        = 0;
10531         int nPlatformEntrySize = 0;
10532         int nPlatformListSize  = 0;
10533         int nPMEMInfoSize = 0;
10534         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
10535         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
10536         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
10537 
10538         nBufHdrSize        = drv_ctx.op_buf.actualcount *
10539             sizeof(OMX_BUFFERHEADERTYPE);
10540         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
10541             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
10542         nPlatformListSize  = drv_ctx.op_buf.actualcount *
10543             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
10544         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
10545             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
10546 
10547         *omx_base_address = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
10548         // Alloc mem for platform specific info
10549         char *pPtr=NULL;
10550         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
10551                 nPMEMInfoSize,1);
10552         *omx_ptr_outputbuffer = (struct vdec_bufferpayload *)    \
10553                        calloc (sizeof(struct vdec_bufferpayload),
10554                                drv_ctx.op_buf.actualcount);
10555         *omx_ptr_respbuffer = (struct vdec_output_frameinfo  *)                         \
10556                      calloc (sizeof (struct vdec_output_frameinfo),
10557                              drv_ctx.op_buf.actualcount);
10558         if (!pPtr || !*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
10559             DEBUG_PRINT_ERROR("allocate_output_headers: allocation failed");
10560             free(pPtr); pPtr = NULL;
10561             free(*omx_ptr_outputbuffer); *omx_ptr_outputbuffer = NULL;
10562             free(*omx_ptr_respbuffer); *omx_ptr_respbuffer = NULL;
10563             return OMX_ErrorInsufficientResources;
10564         }
10565 
10566 #ifdef USE_ION
10567         *omx_op_buf_ion_info = (struct vdec_ion * ) \
10568                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
10569         if (!*omx_op_buf_ion_info) {
10570             DEBUG_PRINT_ERROR("Failed to alloc output buffer ion info");
10571             free(pPtr); pPtr = NULL;
10572             free(*omx_ptr_outputbuffer); *omx_ptr_outputbuffer = NULL;
10573             free(*omx_ptr_respbuffer); *omx_ptr_respbuffer = NULL;
10574             return OMX_ErrorInsufficientResources;
10575         }
10576 #endif
10577 
10578         if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
10579             && *omx_ptr_respbuffer) {
10580             bufHdr          =  *omx_base_address;
10581             if (m_platform_list) {
10582                 free(m_platform_list);
10583             }
10584             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
10585             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
10586                 (((char *) m_platform_list)  + nPlatformListSize);
10587             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
10588                 (((char *) m_platform_entry) + nPlatformEntrySize);
10589             pPlatformList   = m_platform_list;
10590             pPlatformEntry  = m_platform_entry;
10591             pPMEMInfo       = m_pmem_info;
10592 
10593             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
10594 
10595             // Settting the entire storage nicely
10596             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
10597                             *omx_base_address,pPlatformEntry);
10598             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
10599             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
10600                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
10601                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
10602                 // Set the values when we determine the right HxW param
10603                 bufHdr->nAllocLen          = 0;
10604                 bufHdr->nFilledLen         = 0;
10605                 bufHdr->pAppPrivate        = NULL;
10606                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
10607                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
10608                 pPlatformEntry->entry      = pPMEMInfo;
10609                 // Initialize the Platform List
10610                 pPlatformList->nEntries    = 1;
10611                 pPlatformList->entryList   = pPlatformEntry;
10612                 // Keep pBuffer NULL till vdec is opened
10613                 bufHdr->pBuffer            = NULL;
10614                 pPMEMInfo->offset          =  0;
10615                 pPMEMInfo->pmem_fd = -1;
10616                 bufHdr->pPlatformPrivate = pPlatformList;
10617                 (*omx_ptr_outputbuffer)[i].pmem_fd = -1;
10618 #ifdef USE_ION
10619                 (*omx_op_buf_ion_info)[i].data_fd = -1;
10620                 (*omx_op_buf_ion_info)[i].dev_fd = -1;
10621 #endif
10622                 /*Create a mapping between buffers*/
10623                 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
10624                 (*omx_ptr_respbuffer)[i].client_data = (void *) \
10625                     &(*omx_ptr_outputbuffer)[i];
10626                 // Move the buffer and buffer header pointers
10627                 bufHdr++;
10628                 pPMEMInfo++;
10629                 pPlatformEntry++;
10630                 pPlatformList++;
10631             }
10632         } else {
10633             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
10634                               *omx_base_address, pPtr);
10635             if (*omx_base_address) {
10636                 free(*omx_base_address);
10637                 *omx_base_address = NULL;
10638             }
10639             if (pPtr) {
10640                 free(pPtr);
10641                 pPtr = NULL;
10642             }
10643             if (*omx_ptr_outputbuffer) {
10644                 free(*omx_ptr_outputbuffer);
10645                 *omx_ptr_outputbuffer = NULL;
10646             }
10647             if (*omx_ptr_respbuffer) {
10648                 free(*omx_ptr_respbuffer);
10649                 *omx_ptr_respbuffer = NULL;
10650             }
10651 #ifdef USE_ION
10652             if (*omx_op_buf_ion_info) {
10653                 DEBUG_PRINT_LOW("Free o/p ion context");
10654                 free(*omx_op_buf_ion_info);
10655                 *omx_op_buf_ion_info = NULL;
10656             }
10657 #endif
10658             eRet =  OMX_ErrorInsufficientResources;
10659         }
10660     } else {
10661         eRet =  OMX_ErrorInsufficientResources;
10662     }
10663 
10664     if (intermediate == false &&
10665         eRet == OMX_ErrorNone &&
10666         client_buffers.is_color_conversion_enabled()) {
10667         eRet = allocate_output_headers(true);
10668     }
10669 
10670     return eRet;
10671 }
10672 
complete_pending_buffer_done_cbs()10673 void omx_vdec::complete_pending_buffer_done_cbs()
10674 {
10675     unsigned long p1, p2, ident;
10676     omx_cmd_queue tmp_q, pending_bd_q;
10677     pthread_mutex_lock(&m_lock);
10678     // pop all pending GENERATE FDB from ftb queue
10679     while (m_ftb_q.m_size) {
10680         m_ftb_q.pop_entry(&p1,&p2,&ident);
10681         if (ident == OMX_COMPONENT_GENERATE_FBD) {
10682             pending_bd_q.insert_entry(p1,p2,ident);
10683         } else {
10684             tmp_q.insert_entry(p1,p2,ident);
10685         }
10686     }
10687     //return all non GENERATE FDB to ftb queue
10688     while (tmp_q.m_size) {
10689         tmp_q.pop_entry(&p1,&p2,&ident);
10690         m_ftb_q.insert_entry(p1,p2,ident);
10691     }
10692     // pop all pending GENERATE EDB from etb queue
10693     while (m_etb_q.m_size) {
10694         m_etb_q.pop_entry(&p1,&p2,&ident);
10695         if (ident == OMX_COMPONENT_GENERATE_EBD) {
10696             pending_bd_q.insert_entry(p1,p2,ident);
10697         } else {
10698             tmp_q.insert_entry(p1,p2,ident);
10699         }
10700     }
10701     //return all non GENERATE FDB to etb queue
10702     while (tmp_q.m_size) {
10703         tmp_q.pop_entry(&p1,&p2,&ident);
10704         m_etb_q.insert_entry(p1,p2,ident);
10705     }
10706     pthread_mutex_unlock(&m_lock);
10707     // process all pending buffer dones
10708     while (pending_bd_q.m_size) {
10709         pending_bd_q.pop_entry(&p1,&p2,&ident);
10710         switch (ident) {
10711             case OMX_COMPONENT_GENERATE_EBD:
10712                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
10713                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
10714                     omx_report_error ();
10715                 }
10716                 break;
10717 
10718             case OMX_COMPONENT_GENERATE_FBD:
10719                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
10720                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
10721                     omx_report_error ();
10722                 }
10723                 break;
10724         }
10725     }
10726 }
10727 
set_frame_rate(OMX_S64 act_timestamp)10728 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
10729 {
10730     OMX_U32 new_frame_interval = 0;
10731     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
10732             && llabs(act_timestamp - prev_ts) > 2000) {
10733         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
10734             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
10735         if (new_frame_interval != frm_int || frm_int == 0) {
10736             frm_int = new_frame_interval;
10737             if (frm_int) {
10738                 drv_ctx.frame_rate.fps_numerator = 1e6;
10739                 drv_ctx.frame_rate.fps_denominator = frm_int;
10740                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
10741                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
10742                         (float)drv_ctx.frame_rate.fps_denominator);
10743                 /* We need to report the difference between this FBD and the previous FBD
10744                  * back to the driver for clock scaling purposes. */
10745                 struct v4l2_outputparm oparm;
10746                 /*XXX: we're providing timing info as seconds per frame rather than frames
10747                  * per second.*/
10748                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
10749                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
10750 
10751                 struct v4l2_streamparm sparm;
10752                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10753                 sparm.parm.output = oparm;
10754                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
10755                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
10756                             performance might be affected");
10757                 }
10758 
10759             }
10760         }
10761     }
10762     prev_ts = act_timestamp;
10763 }
10764 
adjust_timestamp(OMX_S64 & act_timestamp)10765 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
10766 {
10767     if (rst_prev_ts && VALID_TS(act_timestamp)) {
10768         prev_ts = act_timestamp;
10769         prev_ts_actual = act_timestamp;
10770         rst_prev_ts = false;
10771     } else if (VALID_TS(prev_ts)) {
10772         bool codec_cond = (drv_ctx.timestamp_adjust)?
10773             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
10774             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
10775              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
10776         if (frm_int > 0 && codec_cond) {
10777             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
10778             act_timestamp = prev_ts + frm_int;
10779             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
10780             prev_ts = act_timestamp;
10781         } else {
10782             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
10783                 // ensure that timestamps can never step backwards when in display order
10784                 act_timestamp = prev_ts;
10785             }
10786             set_frame_rate(act_timestamp);
10787         }
10788     } else if (frm_int > 0)          // In this case the frame rate was set along
10789     {                               // with the port definition, start ts with 0
10790         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
10791         rst_prev_ts = true;
10792     }
10793 }
10794 
convert_color_space_info(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer,OMX_U32 matrix,ColorAspects * aspects)10795 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
10796     OMX_U32 transfer, OMX_U32 matrix, ColorAspects *aspects)
10797 {
10798     switch (primaries) {
10799         case MSM_VIDC_BT709_5:
10800             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
10801             break;
10802         case MSM_VIDC_BT470_6_M:
10803             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
10804             break;
10805         case MSM_VIDC_BT601_6_625:
10806             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10807             break;
10808         case MSM_VIDC_BT601_6_525:
10809             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10810             break;
10811         case MSM_VIDC_GENERIC_FILM:
10812             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
10813             break;
10814         case MSM_VIDC_BT2020:
10815             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
10816             break;
10817         case MSM_VIDC_UNSPECIFIED:
10818             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
10819         default:
10820             //aspects->mPrimaries = ColorAspects::PrimariesOther;
10821             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
10822             break;
10823     }
10824 
10825     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
10826 
10827     switch (transfer) {
10828         case MSM_VIDC_TRANSFER_BT709_5:
10829         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
10830         case MSM_VIDC_TRANSFER_BT_2020_10:
10831         case MSM_VIDC_TRANSFER_BT_2020_12:
10832             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10833             break;
10834         case MSM_VIDC_TRANSFER_BT_470_6_M:
10835             aspects->mTransfer = ColorAspects::TransferGamma22;
10836             break;
10837         case MSM_VIDC_TRANSFER_BT_470_6_BG:
10838             aspects->mTransfer = ColorAspects::TransferGamma28;
10839             break;
10840         case MSM_VIDC_TRANSFER_SMPTE_240M:
10841             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10842             break;
10843         case MSM_VIDC_TRANSFER_LINEAR:
10844             aspects->mTransfer = ColorAspects::TransferLinear;
10845             break;
10846         case MSM_VIDC_TRANSFER_IEC_61966:
10847             aspects->mTransfer = ColorAspects::TransferXvYCC;
10848             break;
10849         case MSM_VIDC_TRANSFER_BT_1361:
10850             aspects->mTransfer = ColorAspects::TransferBT1361;
10851             break;
10852         case MSM_VIDC_TRANSFER_SRGB:
10853             aspects->mTransfer = ColorAspects::TransferSRGB;
10854             break;
10855         case MSM_VIDC_TRANSFER_SMPTE_ST2084:
10856             aspects->mTransfer = ColorAspects::TransferST2084;
10857             break;
10858         case MSM_VIDC_TRANSFER_HLG:
10859             aspects->mTransfer = ColorAspects::TransferHLG;
10860             break;
10861         default:
10862             //aspects->mTransfer = ColorAspects::TransferOther;
10863             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
10864             break;
10865     }
10866 
10867     switch (matrix) {
10868         case MSM_VIDC_MATRIX_BT_709_5:
10869             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10870             break;
10871         case MSM_VIDC_MATRIX_FCC_47:
10872             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
10873             break;
10874         case MSM_VIDC_MATRIX_601_6_625:
10875         case MSM_VIDC_MATRIX_601_6_525:
10876             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10877             break;
10878         case MSM_VIDC_MATRIX_SMPTE_240M:
10879             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10880             break;
10881         case MSM_VIDC_MATRIX_BT_2020:
10882             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10883             break;
10884         case MSM_VIDC_MATRIX_BT_2020_CONST:
10885             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
10886             break;
10887         default:
10888             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
10889             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
10890             break;
10891     }
10892 }
10893 
print_debug_color_aspects(ColorAspects * a,const char * prefix)10894 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) {
10895     DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)",
10896                 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange),
10897                 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs));
10898 
10899 }
10900 
handle_color_space_info(void * data)10901 bool omx_vdec::handle_color_space_info(void *data)
10902 {
10903     ColorAspects tempAspects;
10904     memset(&tempAspects, 0x0, sizeof(ColorAspects));
10905     ColorAspects *aspects = &tempAspects;
10906 
10907     switch(output_capability) {
10908         case V4L2_PIX_FMT_MPEG2:
10909             {
10910                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
10911                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
10912 
10913                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
10914                  * understand this code */
10915 
10916                 if (seqdisp_payload && seqdisp_payload->color_descp) {
10917 
10918                     convert_color_space_info(seqdisp_payload->color_primaries, 0,
10919                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
10920                             aspects);
10921                     /* MPEG2 seqdisp payload doesn't give range info. Hence assing the value
10922                      * set by client */
10923                     aspects->mRange = m_client_color_space.sAspects.mRange;
10924                     m_disp_hor_size = seqdisp_payload->disp_width;
10925                     m_disp_vert_size = seqdisp_payload->disp_height;
10926                 }
10927             }
10928             break;
10929         case V4L2_PIX_FMT_H264:
10930         case V4L2_PIX_FMT_HEVC:
10931             {
10932                 struct msm_vidc_vui_display_info_payload *display_info_payload;
10933                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
10934 
10935                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
10936 
10937                 if (display_info_payload->video_signal_present_flag &&
10938                         display_info_payload->color_description_present_flag) {
10939                     convert_color_space_info(display_info_payload->color_primaries,
10940                             display_info_payload->video_full_range_flag,
10941                             display_info_payload->transfer_characteristics,
10942                             display_info_payload->matrix_coefficients,
10943                             aspects);
10944                 }
10945             }
10946             break;
10947         case V4L2_PIX_FMT_VP8:
10948             {
10949                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10950                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10951                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
10952                  * to understand this code */
10953 
10954                 if (vpx_color_space_payload->color_space == 0) {
10955                     aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10956                     aspects->mRange = ColorAspects::RangeLimited;
10957                     aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10958                     aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10959                 } else {
10960                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
10961                     break;
10962                 }
10963             }
10964             break;
10965         case V4L2_PIX_FMT_VP9:
10966             {
10967                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10968                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10969                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
10970                  * to understand this code */
10971 
10972                 switch(vpx_color_space_payload->color_space) {
10973                     case MSM_VIDC_CS_BT_601:
10974                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10975                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10976                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10977                         aspects->mRange = m_client_color_space.sAspects.mRange;
10978                         break;
10979                     case MSM_VIDC_CS_BT_709:
10980                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10981                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10982                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
10983                         aspects->mRange = m_client_color_space.sAspects.mRange;
10984                         break;
10985                     case MSM_VIDC_CS_SMPTE_170:
10986                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10987                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10988                         aspects->mPrimaries =  ColorAspects::PrimariesBT601_6_525;
10989                         aspects->mRange = m_client_color_space.sAspects.mRange;
10990                         break;
10991                     case MSM_VIDC_CS_SMPTE_240:
10992                         aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10993                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10994                         aspects->mPrimaries =  ColorAspects::PrimariesBT601_6_525;
10995                         aspects->mRange = m_client_color_space.sAspects.mRange;
10996                         break;
10997                     case MSM_VIDC_CS_BT_2020:
10998                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10999                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
11000                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
11001                         aspects->mRange = m_client_color_space.sAspects.mRange;
11002                         break;
11003                     case MSM_VIDC_CS_RESERVED:
11004                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
11005                         aspects->mTransfer = ColorAspects::TransferOther;
11006                         aspects->mPrimaries = ColorAspects::PrimariesOther;
11007                         aspects->mRange = m_client_color_space.sAspects.mRange;
11008                         break;
11009                     case MSM_VIDC_CS_RGB:
11010                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
11011                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
11012                         aspects->mPrimaries = ColorAspects::PrimariesOther;
11013                         aspects->mRange = m_client_color_space.sAspects.mRange;
11014                         break;
11015                     default:
11016                         break;
11017                 }
11018             }
11019             break;
11020         default:
11021             break;
11022     }
11023 
11024     print_debug_color_aspects(aspects, "Bitstream");
11025 
11026     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
11027             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
11028             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
11029             m_internal_color_space.sAspects.mRange != aspects->mRange) {
11030         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
11031 
11032         DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change");
11033         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
11034         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
11035 
11036         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
11037                 OMX_QTIIndexConfigDescribeColorAspects,
11038                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
11039         return true;
11040     }
11041     return false;
11042 }
11043 
print_debug_hdr_color_info(HDRStaticInfo * hdr_info,const char * prefix)11044 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix)
11045 {
11046     if (!hdr_info->mID) {
11047         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix,
11048                          hdr_info->sType1.mR.x, hdr_info->sType1.mR.y);
11049         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix,
11050                          hdr_info->sType1.mG.x, hdr_info->sType1.mG.y);
11051         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix,
11052                          hdr_info->sType1.mB.x, hdr_info->sType1.mB.y);
11053         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix,
11054                          hdr_info->sType1.mW.x, hdr_info->sType1.mW.y);
11055         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix,
11056                          hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance);
11057         DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix,
11058                         hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel);
11059     }
11060 
11061 }
11062 
print_debug_hdr_color_info_mdata(ColorMetaData * color_mdata)11063 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata)
11064 {
11065     DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u",
11066                     color_mdata->colorPrimaries, color_mdata->range,
11067                     color_mdata->transfer, color_mdata->matrixCoefficients);
11068 
11069     for(uint8_t i = 0; i < 3; i++) {
11070         for(uint8_t j = 0; j < 2; j++) {
11071             DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
11072         }
11073     }
11074 
11075     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d",
11076                     color_mdata->masteringDisplayInfo.primaries.whitePoint[0],
11077                     color_mdata->masteringDisplayInfo.primaries.whitePoint[1]);
11078 
11079     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d",
11080                     color_mdata->masteringDisplayInfo.maxDisplayLuminance,
11081                     color_mdata->masteringDisplayInfo.minDisplayLuminance);
11082 
11083     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d",
11084                     color_mdata->contentLightLevel.maxContentLightLevel,
11085                     color_mdata->contentLightLevel.minPicAverageLightLevel);
11086 
11087 
11088 }
11089 
handle_content_light_level_info(void * data)11090 bool omx_vdec::handle_content_light_level_info(void* data)
11091 {
11092     struct msm_vidc_content_light_level_sei_payload *light_level_payload =
11093         (msm_vidc_content_light_level_sei_payload*)(data);
11094 
11095     if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) ||
11096         (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) {
11097         m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight;
11098         m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight;
11099         return true;
11100     }
11101     return false;
11102 }
11103 
handle_mastering_display_color_info(void * data)11104 bool omx_vdec::handle_mastering_display_color_info(void* data)
11105 {
11106     struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload =
11107         (msm_vidc_mastering_display_colour_sei_payload*)(data);
11108     HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo;
11109     bool internal_disp_changed_flag = false;
11110 
11111     internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[0]) ||
11112         (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[0]);
11113     internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[1]) ||
11114         (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[1]);
11115     internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[2]) ||
11116         (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[2]);
11117 
11118     internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) ||
11119         (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY);
11120 
11121     /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension
11122        requires it in cd/m2, so dividing by 10000 and rounding the value after division.
11123        Check if max luminance is at least 100 cd/m^2.This check is required for few bistreams where
11124        max luminance is not in correct scale. Use the default max luminance value if the value from
11125        the bitstream is less than 100 cd/m^2.
11126     */
11127 
11128     uint16_t max_display_luminance_cd_m2;
11129     if ((mastering_display_payload->nMaxDisplayMasteringLuminance > 0) &&
11130                         ((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) < 100)) {
11131         max_display_luminance_cd_m2 = LUMINANCE_MAXDISPLAY_CDM2;
11132         DEBUG_PRINT_HIGH("Invalid maxLuminance value from SEI [%.4f]. Using default [%u]",
11133               (mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR),
11134               LUMINANCE_MAXDISPLAY_CDM2);
11135     } else {
11136         max_display_luminance_cd_m2 =
11137         static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5);
11138     }
11139 
11140     internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) ||
11141         (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance);
11142 
11143     if (internal_disp_changed_flag) {
11144         hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[0];
11145         hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[0];
11146         hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[1];
11147         hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[1];
11148         hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[2];
11149         hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[2];
11150         hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX;
11151         hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY;
11152 
11153         hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2;
11154         hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
11155     }
11156 
11157     return internal_disp_changed_flag;
11158 }
11159 
set_colormetadata_in_handle(ColorMetaData * color_mdata,unsigned int buf_index)11160 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index)
11161 {
11162     private_handle_t *private_handle = NULL;
11163     if (buf_index < drv_ctx.op_buf.actualcount &&
11164         buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
11165         native_buffer[buf_index].privatehandle) {
11166         private_handle = native_buffer[buf_index].privatehandle;
11167     }
11168     if (private_handle) {
11169         setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata);
11170     }
11171 }
11172 
convert_color_aspects_to_metadata(ColorAspects & aspects,ColorMetaData & color_mdata)11173 void omx_vdec::convert_color_aspects_to_metadata(ColorAspects& aspects, ColorMetaData &color_mdata)
11174 {
11175     PrimariesMap::const_iterator primary_it = mPrimariesMap.find(aspects.mPrimaries);
11176     TransferMap::const_iterator transfer_it = mTransferMap.find(aspects.mTransfer);
11177     MatrixCoeffMap::const_iterator matrix_it = mMatrixCoeffMap.find(aspects.mMatrixCoeffs);
11178     RangeMap::const_iterator range_it = mColorRangeMap.find(aspects.mRange);
11179 
11180     if (primary_it == mPrimariesMap.end()) {
11181         DEBUG_PRINT_LOW("No mapping for %d in PrimariesMap, defaulting to unspecified", aspects.mPrimaries);
11182         color_mdata.colorPrimaries = (ColorPrimaries)2;
11183     } else {
11184         color_mdata.colorPrimaries = primary_it->second;
11185     }
11186 
11187     if (transfer_it == mTransferMap.end()) {
11188         DEBUG_PRINT_LOW("No mapping for %d in TransferMap, defaulting to unspecified", aspects.mTransfer);
11189         color_mdata.transfer = (GammaTransfer)2;
11190     } else {
11191         color_mdata.transfer = transfer_it->second;
11192     }
11193 
11194     if (matrix_it == mMatrixCoeffMap.end()) {
11195         DEBUG_PRINT_LOW("No mapping for %d in MatrixCoeffMap, defaulting to unspecified", aspects.mMatrixCoeffs);
11196         color_mdata.matrixCoefficients = (MatrixCoEfficients)2;
11197     } else {
11198         color_mdata.matrixCoefficients = matrix_it->second;
11199     }
11200 
11201     if (range_it == mColorRangeMap.end()) {
11202         DEBUG_PRINT_LOW("No mapping for %d in ColorRangeMap, defaulting to limited range", aspects.mRange);
11203         color_mdata.range = Range_Limited;
11204     } else {
11205         color_mdata.range = range_it->second;
11206     }
11207 }
11208 
convert_hdr_info_to_metadata(HDRStaticInfo & hdr_info,ColorMetaData & color_mdata)11209 void omx_vdec::convert_hdr_info_to_metadata(HDRStaticInfo& hdr_info, ColorMetaData &color_mdata)
11210 {
11211     HDRStaticInfo::Type1 zero_hdr_info;
11212     MasteringDisplay& mastering_display = color_mdata.masteringDisplayInfo;
11213     ContentLightLevel& content_light = color_mdata.contentLightLevel;
11214     bool hdr_info_enabled = false;
11215     memset(&zero_hdr_info, 0, sizeof(HDRStaticInfo::Type1));
11216     hdr_info_enabled = (memcmp(&hdr_info, &zero_hdr_info, sizeof(HDRStaticInfo::Type1))!= 0);
11217 
11218     if (hdr_info_enabled) {
11219         mastering_display.colorVolumeSEIEnabled = true;
11220         mastering_display.primaries.rgbPrimaries[0][0] = hdr_info.sType1.mR.x;
11221         mastering_display.primaries.rgbPrimaries[0][1] = hdr_info.sType1.mR.y;
11222         mastering_display.primaries.rgbPrimaries[1][0] = hdr_info.sType1.mG.x;
11223         mastering_display.primaries.rgbPrimaries[1][1] = hdr_info.sType1.mG.y;
11224         mastering_display.primaries.rgbPrimaries[2][0] = hdr_info.sType1.mB.x;
11225         mastering_display.primaries.rgbPrimaries[2][1] = hdr_info.sType1.mB.y;
11226         mastering_display.primaries.whitePoint[0] = hdr_info.sType1.mW.x;
11227         mastering_display.primaries.whitePoint[1] = hdr_info.sType1.mW.y;
11228         mastering_display.maxDisplayLuminance = hdr_info.sType1.mMaxDisplayLuminance;
11229         mastering_display.minDisplayLuminance = hdr_info.sType1.mMinDisplayLuminance;
11230         content_light.lightLevelSEIEnabled = true;
11231         content_light.maxContentLightLevel = hdr_info.sType1.mMaxContentLightLevel;
11232         content_light.minPicAverageLightLevel = hdr_info.sType1.mMaxFrameAverageLightLevel;
11233     }
11234 
11235 }
11236 
get_preferred_color_aspects(ColorAspects & preferredColorAspects)11237 void omx_vdec::get_preferred_color_aspects(ColorAspects& preferredColorAspects)
11238 {
11239     OMX_U32 width = drv_ctx.video_resolution.frame_width;
11240     OMX_U32 height = drv_ctx.video_resolution.frame_height;
11241 
11242     // For VPX, use client-color if specified.
11243     // For the rest, try to use the stream-color if present
11244     bool preferClientColor = (output_capability == V4L2_PIX_FMT_VP8 ||
11245          output_capability == V4L2_PIX_FMT_VP9);
11246 
11247     const ColorAspects &preferredColor = preferClientColor ?
11248         m_client_color_space.sAspects : m_internal_color_space.sAspects;
11249     const ColorAspects &defaultColor = preferClientColor ?
11250         m_internal_color_space.sAspects : m_client_color_space.sAspects;
11251 
11252     if ((width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) &&
11253         (m_client_color_space.sAspects.mPrimaries == ColorAspects::PrimariesBT2020) &&
11254         (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8)) {
11255         m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesBT709_5;
11256         m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixBT709_5;
11257     }
11258 
11259     preferredColorAspects.mPrimaries = preferredColor.mPrimaries != ColorAspects::PrimariesUnspecified ?
11260         preferredColor.mPrimaries : defaultColor.mPrimaries;
11261     preferredColorAspects.mTransfer = preferredColor.mTransfer != ColorAspects::TransferUnspecified ?
11262         preferredColor.mTransfer : defaultColor.mTransfer;
11263     preferredColorAspects.mMatrixCoeffs = preferredColor.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
11264         preferredColor.mMatrixCoeffs : defaultColor.mMatrixCoeffs;
11265     preferredColorAspects.mRange = preferredColor.mRange != ColorAspects::RangeUnspecified ?
11266         preferredColor.mRange : defaultColor.mRange;
11267 
11268 }
11269 
get_preferred_hdr_info(HDRStaticInfo & finalHDRInfo)11270 void omx_vdec::get_preferred_hdr_info(HDRStaticInfo& finalHDRInfo)
11271 {
11272     bool preferClientHDR = (output_capability == V4L2_PIX_FMT_VP9);
11273 
11274     const HDRStaticInfo &preferredHDRInfo = preferClientHDR ?
11275         m_client_hdr_info.sInfo : m_internal_hdr_info.sInfo;
11276     const HDRStaticInfo &defaultHDRInfo = preferClientHDR ?
11277         m_internal_hdr_info.sInfo : m_client_hdr_info.sInfo;
11278     finalHDRInfo.sType1.mR = ((preferredHDRInfo.sType1.mR.x != 0) && (preferredHDRInfo.sType1.mR.y != 0)) ?
11279         preferredHDRInfo.sType1.mR : defaultHDRInfo.sType1.mR;
11280     finalHDRInfo.sType1.mG = ((preferredHDRInfo.sType1.mG.x != 0) && (preferredHDRInfo.sType1.mG.y != 0)) ?
11281         preferredHDRInfo.sType1.mG : defaultHDRInfo.sType1.mG;
11282     finalHDRInfo.sType1.mB = ((preferredHDRInfo.sType1.mB.x != 0) && (preferredHDRInfo.sType1.mB.y != 0)) ?
11283         preferredHDRInfo.sType1.mB : defaultHDRInfo.sType1.mB;
11284     finalHDRInfo.sType1.mW = ((preferredHDRInfo.sType1.mW.x != 0) && (preferredHDRInfo.sType1.mW.y != 0)) ?
11285         preferredHDRInfo.sType1.mW : defaultHDRInfo.sType1.mW;
11286     finalHDRInfo.sType1.mMaxDisplayLuminance = (preferredHDRInfo.sType1.mMaxDisplayLuminance != 0) ?
11287         preferredHDRInfo.sType1.mMaxDisplayLuminance : defaultHDRInfo.sType1.mMaxDisplayLuminance;
11288     finalHDRInfo.sType1.mMinDisplayLuminance = (preferredHDRInfo.sType1.mMinDisplayLuminance != 0) ?
11289         preferredHDRInfo.sType1.mMinDisplayLuminance : defaultHDRInfo.sType1.mMinDisplayLuminance;
11290     finalHDRInfo.sType1.mMaxContentLightLevel = (preferredHDRInfo.sType1.mMaxContentLightLevel != 0) ?
11291         preferredHDRInfo.sType1.mMaxContentLightLevel : defaultHDRInfo.sType1.mMaxContentLightLevel;
11292     finalHDRInfo.sType1.mMaxFrameAverageLightLevel = (preferredHDRInfo.sType1.mMaxFrameAverageLightLevel != 0) ?
11293         preferredHDRInfo.sType1.mMaxFrameAverageLightLevel : defaultHDRInfo.sType1.mMaxFrameAverageLightLevel;
11294 }
11295 
print_debug_hdr10plus_metadata(ColorMetaData & color_mdata)11296 void omx_vdec::print_debug_hdr10plus_metadata(ColorMetaData& color_mdata) {
11297     DEBUG_PRINT_LOW("HDR10+ valid data length: %d", color_mdata.dynamicMetaDataLen);
11298     for (uint32_t i = 0 ; i < color_mdata.dynamicMetaDataLen && i+3 < HDR_DYNAMIC_META_DATA_SZ; i=i+4) {
11299         DEBUG_PRINT_LOW("HDR10+ mdata: %02X %02X %02X %02X", color_mdata.dynamicMetaDataPayload[i],
11300             color_mdata.dynamicMetaDataPayload[i+1],
11301             color_mdata.dynamicMetaDataPayload[i+2],
11302             color_mdata.dynamicMetaDataPayload[i+3]);
11303     }
11304 
11305 }
11306 
handle_extradata(OMX_BUFFERHEADERTYPE * p_buf_hdr)11307 bool omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
11308 {
11309     OMX_OTHER_EXTRADATATYPE *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
11310     OMX_U32 num_conceal_MB = 0;
11311     OMX_TICKS time_stamp = 0;
11312     OMX_U32 frame_rate = 0;
11313     unsigned long consumed_len = 0;
11314     OMX_U32 num_MB_in_frame;
11315     OMX_U32 recovery_sei_flags = 1;
11316     int enable = OMX_InterlaceFrameProgressive;
11317     bool internal_hdr_info_changed_flag = false;
11318     bool reconfig_event_sent = false;
11319     char *p_extradata = NULL;
11320     OMX_OTHER_EXTRADATATYPE *data = NULL;
11321     ColorMetaData color_mdata;
11322 
11323     OMX_BUFFERHEADERTYPE  *omx_base_address =
11324         client_buffers.is_color_conversion_enabled()?
11325                             m_intermediate_out_mem_ptr:m_out_mem_ptr;
11326     vdec_bufferpayload *omx_ptr_outputbuffer =
11327         client_buffers.is_color_conversion_enabled()?
11328                     drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
11329     memset(&color_mdata, 0, sizeof(color_mdata));
11330 
11331     int buf_index = p_buf_hdr - omx_base_address;
11332     if (buf_index >= drv_ctx.extradata_info.count) {
11333         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
11334                 buf_index, drv_ctx.extradata_info.count);
11335         return reconfig_event_sent;
11336     }
11337     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
11338 
11339     if (omx_ptr_outputbuffer[buf_index].bufferaddr == NULL) {
11340         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
11341         return reconfig_event_sent;
11342     }
11343 
11344     if (!drv_ctx.extradata_info.uaddr) {
11345         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
11346         return reconfig_event_sent;
11347     }
11348 
11349     if (m_client_output_extradata_mem_ptr &&
11350         m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
11351         p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer);
11352     }
11353 
11354     p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
11355 
11356     m_extradata_info.output_crop_updated = OMX_FALSE;
11357     data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
11358     if (data) {
11359         while ((((consumed_len + sizeof(struct OMX_OTHER_EXTRADATATYPE)) <
11360                 drv_ctx.extradata_info.buffer_size) && ((consumed_len + data->nSize) <
11361                 drv_ctx.extradata_info.buffer_size))
11362                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
11363             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
11364             switch ((unsigned long)data->eType) {
11365                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
11366                     struct msm_vidc_interlace_payload *payload;
11367                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
11368                     if (payload) {
11369                         DEBUG_PRINT_LOW("Interlace format %#x", payload->format);
11370                         enable = OMX_InterlaceFrameProgressive;
11371                         is_mbaff = payload->format & MSM_VIDC_INTERLACE_FRAME_MBAFF;
11372                         switch (payload->format & 0x1F) {
11373                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
11374                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11375                                 break;
11376                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
11377                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
11378                                 enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
11379                                 break;
11380                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
11381                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
11382                                 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
11383                                 break;
11384                             case MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST:
11385                                 drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
11386                                 enable = OMX_InterlaceFrameTopFieldFirst;
11387                                 break;
11388                            case MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST:
11389                                 drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
11390                                 enable = OMX_InterlaceFrameBottomFieldFirst;
11391                                 break;
11392                             default:
11393                                 DEBUG_PRINT_LOW("default case - set to progressive");
11394                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11395                         }
11396                     }
11397 
11398                     if (m_enable_android_native_buffers) {
11399                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d enable:%d",
11400                                         payload->format, enable);
11401 
11402                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
11403                                PP_PARAM_INTERLACED, (void*)&enable);
11404 
11405                     }
11406                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
11407                         if (p_client_extra) {
11408                             append_interlace_extradata(p_client_extra, (payload->format & 0x1F));
11409                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
11410                                 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11411                         }
11412                     }
11413                     break;
11414                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
11415                     struct msm_vidc_framerate_payload *frame_rate_payload;
11416                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
11417                     frame_rate = frame_rate_payload->frame_rate;
11418                     break;
11419                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
11420                     struct msm_vidc_ts_payload *time_stamp_payload;
11421                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
11422                     time_stamp = time_stamp_payload->timestamp_lo;
11423                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
11424                     p_buf_hdr->nTimeStamp = time_stamp;
11425                     break;
11426                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
11427                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
11428                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
11429                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11430                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11431                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
11432                     break;
11433                 case MSM_VIDC_EXTRADATA_INDEX:
11434                     int *etype;
11435                     etype  = (int *)(void *)data->data;
11436                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
11437                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
11438                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
11439                         if (aspect_ratio_payload) {
11440                             ((struct vdec_output_frameinfo *)
11441                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
11442                             ((struct vdec_output_frameinfo *)
11443                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
11444                         }
11445                     } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
11446                         struct msm_vidc_output_crop_payload *output_crop_payload;
11447                         output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
11448                         if (output_crop_payload) {
11449                             m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
11450                             m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
11451                             m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
11452                             m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
11453                             m_extradata_info.output_width = output_crop_payload->width;
11454                             m_extradata_info.output_height = output_crop_payload->height;
11455                             m_extradata_info.output_crop_updated = OMX_TRUE;
11456                             for(unsigned int m=0; m<output_crop_payload->misr_info[0].misr_set; m++) {
11457                             DEBUG_PRINT_HIGH("MISR0: %x %x %x %x\n",
11458                                 output_crop_payload->misr_info[0].misr_dpb_luma[m],
11459                                 output_crop_payload->misr_info[0].misr_dpb_chroma[m],
11460                                 output_crop_payload->misr_info[0].misr_opb_luma[m],
11461                                 output_crop_payload->misr_info[0].misr_opb_chroma[m]);
11462                             }
11463                             for(unsigned int m=0; m< output_crop_payload->misr_info[1].misr_set; m++) {
11464                                 DEBUG_PRINT_HIGH("MISR1: %x %x %x %x\n",
11465                                                  output_crop_payload->misr_info[1].misr_dpb_luma[m],
11466                                                  output_crop_payload->misr_info[1].misr_dpb_chroma[m],
11467                                                  output_crop_payload->misr_info[1].misr_opb_luma[m],
11468                                                  output_crop_payload->misr_info[1].misr_opb_chroma[m]);
11469                             }
11470                             memcpy(m_extradata_info.misr_info, output_crop_payload->misr_info, 2 * sizeof(msm_vidc_misr_info));
11471                             if (client_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11472                                 if (p_client_extra) {
11473                                     append_outputcrop_extradata(p_client_extra, output_crop_payload);
11474                                     p_client_extra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11475                                 }
11476                             }
11477                         }
11478                     }
11479                     break;
11480                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
11481                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
11482                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
11483                     recovery_sei_flags = recovery_sei_payload->flags;
11484                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
11485                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
11486                         DEBUG_PRINT_HIGH("***************************************************");
11487                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
11488                         DEBUG_PRINT_HIGH("***************************************************");
11489                     }
11490                     break;
11491                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
11492                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
11493                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
11494                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
11495                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
11496                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
11497                         return reconfig_event_sent;
11498                     }
11499                     break;
11500                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
11501                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
11502                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
11503                     reconfig_event_sent |= handle_color_space_info((void *)data->data);
11504                     break;
11505                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
11506                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
11507                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
11508                     switch (s3d_frame_packing_payload->fpa_type) {
11509                         case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
11510                             if (s3d_frame_packing_payload->content_interprtation_type == 1)
11511                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
11512                             else if (s3d_frame_packing_payload->content_interprtation_type == 2)
11513                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
11514                             else {
11515                                 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
11516                                 stereo_output_mode = HAL_NO_3D;
11517                             }
11518                             break;
11519                         case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
11520                             stereo_output_mode = HAL_3D_TOP_BOTTOM;
11521                             break;
11522                         default:
11523                             DEBUG_PRINT_ERROR("Unsupported framepacking type");
11524                             stereo_output_mode = HAL_NO_3D;
11525                     }
11526                     DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
11527                         s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
11528                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
11529                         if (p_client_extra) {
11530                             append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
11531                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11532                         }
11533                     }
11534                     break;
11535                 case MSM_VIDC_EXTRADATA_FRAME_QP:
11536                     struct msm_vidc_frame_qp_payload *qp_payload;
11537                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
11538                     if (client_extradata & OMX_QP_EXTRADATA) {
11539                         if (p_client_extra) {
11540                             append_qp_extradata(p_client_extra, qp_payload);
11541                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11542                         }
11543                     }
11544                     break;
11545                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
11546                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
11547                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
11548                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
11549                         if (p_client_extra) {
11550                             append_bitsinfo_extradata(p_client_extra, bits_info_payload);
11551                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11552                         }
11553                     }
11554                     break;
11555                 case MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO:
11556                     DEBUG_PRINT_LOW("MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO not used. Ignoring.");
11557                     break;
11558                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
11559                     if(output_capability == V4L2_PIX_FMT_HEVC) {
11560                         struct msm_vidc_stream_userdata_payload* userdata_payload = (struct msm_vidc_stream_userdata_payload*)data->data;
11561                         // Remove the size of type from msm_vidc_stream_userdata_payload
11562                         uint32_t payload_len = data->nDataSize - sizeof(userdata_payload->type);
11563                         if ((data->nDataSize < sizeof(userdata_payload->type)) ||
11564                             (payload_len > HDR_DYNAMIC_META_DATA_SZ)) {
11565                             DEBUG_PRINT_ERROR("Invalid User extradata size %u for HDR10+", data->nDataSize);
11566                         } else {
11567 // enable setting metadata via gralloc handle
11568 //#if HDR10_SETMETADATA_ENABLE
11569                             color_mdata.dynamicMetaDataValid = true;
11570                             color_mdata.dynamicMetaDataLen = payload_len;
11571                             memcpy(color_mdata.dynamicMetaDataPayload, userdata_payload->data, payload_len);
11572                             DEBUG_PRINT_HIGH("Copied %u bytes of HDR10+ extradata", payload_len);
11573 //#endif
11574                             store_hevc_hdr10plusinfo(payload_len, userdata_payload);
11575                         }
11576                     }
11577                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
11578                         if (p_client_extra) {
11579                             append_user_extradata(p_client_extra, data);
11580                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11581                         }
11582                     }
11583                     break;
11584                 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
11585 
11586                     internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data);
11587                     break;
11588                 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI:
11589                     internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data);
11590                     break;
11591                 default:
11592                     DEBUG_PRINT_LOW("Unrecognized extradata");
11593                     goto unrecognized_extradata;
11594             }
11595             consumed_len += data->nSize;
11596             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
11597         }
11598         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
11599             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11600             if (p_client_extra) {
11601                 append_frame_info_extradata(p_client_extra,
11602                         num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
11603                         time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
11604                             p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
11605                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11606             }
11607         }
11608         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
11609             if (p_client_extra) {
11610                 append_frame_dimension_extradata(p_client_extra);
11611                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11612             }
11613         }
11614 
11615         if(internal_hdr_info_changed_flag) {
11616             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal");
11617             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client");
11618             if(!reconfig_event_sent) {
11619                 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change");
11620                 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
11621                            OMX_QTIIndexConfigDescribeHDRColorInfo,
11622                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
11623                 reconfig_event_sent = true;
11624             }
11625         }
11626 
11627         if (m_enable_android_native_buffers) {
11628                 ColorAspects final_color_aspects;
11629                 HDRStaticInfo final_hdr_info;
11630                 memset(&final_color_aspects, 0, sizeof(final_color_aspects));
11631                 memset(&final_hdr_info, 0, sizeof(final_hdr_info));
11632                 get_preferred_color_aspects(final_color_aspects);
11633 
11634                 /* For VP8, always set the metadata on gralloc handle to 601-LR */
11635                 if (output_capability == V4L2_PIX_FMT_VP8) {
11636                     final_color_aspects.mPrimaries = ColorAspects::PrimariesBT601_6_525;
11637                     final_color_aspects.mRange = ColorAspects::RangeLimited;
11638                     final_color_aspects.mTransfer = ColorAspects::TransferSMPTE170M;
11639                     final_color_aspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
11640                 }
11641                 get_preferred_hdr_info(final_hdr_info);
11642 // enable setting metadata via gralloc handle
11643 //#if HDR10_SETMETADATA_ENABLE
11644                 convert_hdr_info_to_metadata(final_hdr_info, color_mdata);
11645                 convert_hdr10plusinfo_to_metadata(p_buf_hdr->pMarkData, color_mdata);
11646                 remove_hdr10plusinfo_using_cookie(p_buf_hdr->pMarkData);
11647                 convert_color_aspects_to_metadata(final_color_aspects, color_mdata);
11648                 print_debug_hdr_color_info_mdata(&color_mdata);
11649                 print_debug_hdr10plus_metadata(color_mdata);
11650                 set_colormetadata_in_handle(&color_mdata, buf_index);
11651 //#endif
11652         }
11653 
11654     }
11655 unrecognized_extradata:
11656     if (client_extradata) {
11657         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11658         if (p_client_extra) {
11659             append_terminator_extradata(p_client_extra);
11660         }
11661     }
11662     return reconfig_event_sent;
11663 }
11664 
enable_extradata(OMX_U64 requested_extradata,bool is_internal,bool enable)11665 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata,
11666         bool is_internal, bool enable)
11667 {
11668     OMX_ERRORTYPE ret = OMX_ErrorNone;
11669     struct v4l2_control control;
11670     if (m_state != OMX_StateLoaded) {
11671         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
11672         return OMX_ErrorIncorrectStateOperation;
11673     }
11674     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
11675             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
11676 
11677     if (!is_internal) {
11678         if (enable)
11679             client_extradata |= requested_extradata;
11680         else
11681             client_extradata = client_extradata & ~requested_extradata;
11682     }
11683 
11684     if (enable) {
11685         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
11686             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11687             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
11688             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11689                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
11690                         " Quality of interlaced clips might be impacted.");
11691             }
11692         }
11693         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
11694             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11695             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
11696             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11697                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
11698             }
11699             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11700             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
11701             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11702                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
11703             }
11704             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11705             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
11706             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11707                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
11708             }
11709             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11710             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
11711             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11712                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11713             }
11714             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11715             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
11716             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11717                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11718             }
11719             if (output_capability == V4L2_PIX_FMT_MPEG2) {
11720                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11721                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11722                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11723                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11724                 }
11725             }
11726         }
11727         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
11728             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11729             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
11730             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11731                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
11732             }
11733         }
11734         if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
11735             if (output_capability == V4L2_PIX_FMT_H264) {
11736                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
11737                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11738                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
11739                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11740                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
11741                 }
11742             } else {
11743                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
11744             }
11745         }
11746         if (requested_extradata & OMX_QP_EXTRADATA) {
11747             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11748             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11749             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11750                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11751             }
11752         }
11753         if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
11754             if (!secure_mode || (secure_mode && output_capability == V4L2_PIX_FMT_HEVC)) {
11755                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11756                 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
11757                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11758                     DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
11759                 }
11760             }
11761         }
11762 #if NEED_TO_REVISIT
11763         if (requested_extradata & OMX_QP_EXTRADATA) {
11764             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11765             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11766             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11767                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11768             }
11769         }
11770 #endif
11771         if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11772             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11773             control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
11774             DEBUG_PRINT_LOW("Enable output crop extra data");
11775             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11776                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11777             }
11778         }
11779         if (requested_extradata & OMX_UBWC_CR_STATS_INFO_EXTRADATA) {
11780             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11781             control.value = V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO;
11782             DEBUG_PRINT_LOW("Enable UBWC stats extra data");
11783             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11784                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11785             }
11786         }
11787         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
11788             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11789             switch(output_capability) {
11790                 case V4L2_PIX_FMT_H264:
11791                 case V4L2_PIX_FMT_HEVC:
11792                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
11793                     break;
11794                 case V4L2_PIX_FMT_VP8:
11795                 case V4L2_PIX_FMT_VP9:
11796                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
11797                     break;
11798                 case V4L2_PIX_FMT_MPEG2:
11799                     control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11800                     break;
11801                 default:
11802                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
11803                     return ret;
11804             }
11805 
11806             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11807                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
11808             }
11809         }
11810         if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) {
11811             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11812             if (output_capability == V4L2_PIX_FMT_HEVC) {
11813                 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI;
11814                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11815                     DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata");
11816                 }
11817                 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
11818                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11819                     DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata");
11820                 }
11821             } else {
11822                 DEBUG_PRINT_HIGH("OMX_HDR_COLOR_INFO_EXTRADATA supported for HEVC only");
11823             }
11824         }
11825     }
11826     ret = get_buffer_req(&drv_ctx.op_buf);
11827     return ret;
11828 }
11829 
count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE * extra)11830 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11831 {
11832     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
11833     OMX_U8 *data_ptr = extra->data, data = 0;
11834     while (byte_count < extra->nDataSize) {
11835         data = *data_ptr;
11836         while (data) {
11837             num_MB += (data&0x01);
11838             data >>= 1;
11839         }
11840         data_ptr++;
11841         byte_count++;
11842     }
11843     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11844             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11845     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
11846 }
11847 
print_debug_extradata(OMX_OTHER_EXTRADATATYPE * extra)11848 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11849 {
11850     if (!m_debug_extradata || !extra)
11851         return;
11852 
11853 
11854     DEBUG_PRINT_HIGH(
11855             "============== Extra Data ==============\n"
11856             "           Size: %u\n"
11857             "        Version: %u\n"
11858             "      PortIndex: %u\n"
11859             "           Type: %x\n"
11860             "       DataSize: %u",
11861             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
11862             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
11863 
11864     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
11865         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
11866         DEBUG_PRINT_HIGH(
11867                 "------ Interlace Format ------\n"
11868                 "                Size: %u\n"
11869                 "             Version: %u\n"
11870                 "           PortIndex: %u\n"
11871                 " Is Interlace Format: %d\n"
11872                 "   Interlace Formats: %u\n"
11873                 "=========== End of Interlace ===========",
11874                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
11875                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
11876     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
11877         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
11878 
11879         DEBUG_PRINT_HIGH(
11880                 "-------- Frame Format --------\n"
11881                 "             Picture Type: %d\n"
11882                 "           Interlace Type: %d\n"
11883                 " Pan Scan Total Frame Num: %u\n"
11884                 "   Concealed Macro Blocks: %u\n"
11885                 "        Recovery SEI Flag: %u\n"
11886                 "               frame rate: %u\n"
11887                 "               Time Stamp: %llu\n"
11888                 "           Aspect Ratio X: %u\n"
11889                 "           Aspect Ratio Y: %u",
11890                 fminfo->ePicType,
11891                 fminfo->interlaceType,
11892                 (unsigned int)fminfo->panScan.numWindows,
11893                 (unsigned int)fminfo->nConcealedMacroblocks,
11894                 (unsigned int)fminfo->nRecoverySeiFlag,
11895                 (unsigned int)fminfo->nFrameRate,
11896                 fminfo->nTimeStamp,
11897                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
11898                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
11899 
11900         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
11901             DEBUG_PRINT_HIGH(
11902                     "------------------------------"
11903                     "     Pan Scan Frame Num: %u\n"
11904                     "            Rectangle x: %d\n"
11905                     "            Rectangle y: %d\n"
11906                     "           Rectangle dx: %d\n"
11907                     "           Rectangle dy: %d",
11908                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
11909                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
11910         }
11911 
11912         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
11913     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
11914         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
11915         DEBUG_PRINT_HIGH(
11916                 "------------------ Framepack Format ----------\n"
11917                 "                           id: %u \n"
11918                 "                  cancel_flag: %u \n"
11919                 "                         type: %u \n"
11920                 " quincunx_sampling_flagFormat: %u \n"
11921                 "  content_interpretation_type: %u \n"
11922                 "        spatial_flipping_flag: %u \n"
11923                 "          frame0_flipped_flag: %u \n"
11924                 "             field_views_flag: %u \n"
11925                 " current_frame_is_frame0_flag: %u \n"
11926                 "   frame0_self_contained_flag: %u \n"
11927                 "   frame1_self_contained_flag: %u \n"
11928                 "       frame0_grid_position_x: %u \n"
11929                 "       frame0_grid_position_y: %u \n"
11930                 "       frame1_grid_position_x: %u \n"
11931                 "       frame1_grid_position_y: %u \n"
11932                 "                reserved_byte: %u \n"
11933                 "            repetition_period: %u \n"
11934                 "               extension_flag: %u \n"
11935                 "================== End of Framepack ===========",
11936                 (unsigned int)framepack->id,
11937                 (unsigned int)framepack->cancel_flag,
11938                 (unsigned int)framepack->type,
11939                 (unsigned int)framepack->quincunx_sampling_flag,
11940                 (unsigned int)framepack->content_interpretation_type,
11941                 (unsigned int)framepack->spatial_flipping_flag,
11942                 (unsigned int)framepack->frame0_flipped_flag,
11943                 (unsigned int)framepack->field_views_flag,
11944                 (unsigned int)framepack->current_frame_is_frame0_flag,
11945                 (unsigned int)framepack->frame0_self_contained_flag,
11946                 (unsigned int)framepack->frame1_self_contained_flag,
11947                 (unsigned int)framepack->frame0_grid_position_x,
11948                 (unsigned int)framepack->frame0_grid_position_y,
11949                 (unsigned int)framepack->frame1_grid_position_x,
11950                 (unsigned int)framepack->frame1_grid_position_y,
11951                 (unsigned int)framepack->reserved_byte,
11952                 (unsigned int)framepack->repetition_period,
11953                 (unsigned int)framepack->extension_flag);
11954     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
11955         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
11956         DEBUG_PRINT_HIGH(
11957                 "---- QP (Frame quantization parameter) ----\n"
11958                 "              Frame QP: %u \n"
11959                 "       Sum of Frame QP: %u \n"
11960                 "     Sum of Skipped QP: %u \n"
11961                 "    Num Skipped Blocks: %u \n"
11962                 "          Total Blocks: %u \n"
11963                 "================ End of QP ================\n",
11964                 (unsigned int)qp->nQP,(unsigned int)qp->nQPSum,
11965                 (unsigned int)qp->nSkipQPSum,(unsigned int)qp->nSkipNumBlocks,
11966                 (unsigned int)qp->nTotalNumBlocks);
11967     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
11968         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
11969         DEBUG_PRINT_HIGH(
11970                 "--------- Input bits information --------\n"
11971                 "    Header bits: %u \n"
11972                 "     Frame bits: %u \n"
11973                 "===== End of Input bits information =====\n",
11974                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
11975     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
11976         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
11977         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
11978         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
11979         OMX_U32 i = 0;
11980         DEBUG_PRINT_HIGH(
11981                 "--------------  Userdata  -------------\n"
11982                 "    Stream userdata type: %u\n"
11983                 "          userdata size: %u\n"
11984                 "    STREAM_USERDATA:",
11985                 (unsigned int)userdata->type, (unsigned int)userdata_size);
11986                 for (i = 0; i < userdata_size; i+=4) {
11987                     DEBUG_PRINT_HIGH("        %x %x %x %x",
11988                         data_ptr[i], data_ptr[i+1],
11989                         data_ptr[i+2], data_ptr[i+3]);
11990                 }
11991         DEBUG_PRINT_HIGH(
11992                 "=========== End of Userdata ===========");
11993     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
11994         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
11995         DEBUG_PRINT_HIGH(
11996                 "--------------  VQZip  -------------\n"
11997                 "    Size: %u\n",
11998                 (unsigned int)vq->nSize);
11999         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
12000     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo) {
12001         OMX_QCOM_OUTPUT_CROP *outputcrop_info = (OMX_QCOM_OUTPUT_CROP*)(void *)extra->data;
12002         DEBUG_PRINT_HIGH(
12003             "------------------ output crop ----------\n"
12004             "                         left: %u \n"
12005             "                          top: %u \n"
12006             "                display_width: %u \n"
12007             "               display_height: %u \n"
12008             "                        width: %u \n"
12009             "                       height: %u \n"
12010             "                    frame_num: %u \n"
12011             "                  bit_depth_y: %u \n"
12012             "                  bit_depth_c: %u \n",
12013             (unsigned int)outputcrop_info->left,
12014             (unsigned int)outputcrop_info->top,
12015             (unsigned int)outputcrop_info->display_width,
12016             (unsigned int)outputcrop_info->display_height,
12017             (unsigned int)outputcrop_info->width,
12018             (unsigned int)outputcrop_info->height,
12019             (unsigned int)outputcrop_info->frame_num,
12020             (unsigned int)outputcrop_info->bit_depth_y,
12021             (unsigned int)outputcrop_info->bit_depth_c);
12022         for(unsigned int m=0; m<outputcrop_info->misr_info[0].misr_set; m++) {
12023             DEBUG_PRINT_HIGH(
12024             "     top field: misr_dpb_luma(%d): %u \n"
12025             "   top field: misr_dpb_chroma(%d): %u \n"
12026             "     top field: misr_opb_luma(%d): %u \n"
12027             "   top field: misr_opb_chroma(%d): %u \n",
12028             m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_luma[m],
12029             m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_chroma[m],
12030             m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_luma[m],
12031             m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_chroma[m]);
12032         }
12033         for(unsigned int m=0; m<outputcrop_info->misr_info[1].misr_set; m++) {
12034             DEBUG_PRINT_HIGH(
12035             "  bottom field: misr_dpb_luma(%d): %u \n"
12036             "bottom field: misr_dpb_chroma(%d): %u \n"
12037             "  bottom field: misr_opb_luma(%d): %u \n"
12038             "bottom field: misr_opb_chroma(%d): %u \n",
12039             m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_luma[m],
12040             m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_chroma[m],
12041             m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_luma[m],
12042             m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_chroma[m]);
12043         }
12044         DEBUG_PRINT_HIGH("================== End of output crop ===========");
12045     } else if (extra->eType == OMX_ExtraDataNone) {
12046         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
12047     } else {
12048         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
12049     }
12050 }
12051 
append_interlace_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_U32 interlaced_format_type)12052 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12053         OMX_U32 interlaced_format_type)
12054 {
12055     OMX_STREAMINTERLACEFORMAT *interlace_format;
12056 
12057     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
12058         return;
12059     }
12060     if (!extra) {
12061        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
12062        return;
12063     }
12064     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
12065     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12066     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12067     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
12068     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
12069     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
12070     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
12071     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
12072     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12073 
12074     if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
12075         interlace_format->bInterlaceFormat = OMX_FALSE;
12076         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
12077         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
12078     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
12079         interlace_format->bInterlaceFormat = OMX_TRUE;
12080         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
12081         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
12082     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
12083         interlace_format->bInterlaceFormat = OMX_TRUE;
12084         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
12085         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
12086     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST) {
12087         interlace_format->bInterlaceFormat = OMX_TRUE;
12088         interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
12089         drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
12090     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST) {
12091         interlace_format->bInterlaceFormat = OMX_TRUE;
12092         interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
12093         drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
12094     } else {
12095         //default case - set to progressive
12096         interlace_format->bInterlaceFormat = OMX_FALSE;
12097         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
12098         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
12099     }
12100     print_debug_extradata(extra);
12101 }
12102 
append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE * extra)12103 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12104 {
12105     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
12106     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
12107         return;
12108     }
12109     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
12110     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12111     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12112     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
12113     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
12114     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
12115     frame_dimension->nDecWidth = rectangle.nLeft;
12116     frame_dimension->nDecHeight = rectangle.nTop;
12117     frame_dimension->nActualWidth = rectangle.nWidth;
12118     frame_dimension->nActualHeight = rectangle.nHeight;
12119 }
12120 
fill_aspect_ratio_info(struct vdec_aspectratioinfo * aspect_ratio_info,OMX_QCOM_EXTRADATA_FRAMEINFO * frame_info)12121 void omx_vdec::fill_aspect_ratio_info(
12122         struct vdec_aspectratioinfo *aspect_ratio_info,
12123         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
12124 {
12125     m_extradata = frame_info;
12126     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
12127     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
12128     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
12129             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
12130 }
12131 
append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_U32 num_conceal_mb,OMX_U32 recovery_sei_flag,OMX_U32 picture_type,OMX_U32 frame_rate,OMX_TICKS time_stamp,struct msm_vidc_panscan_window_payload * panscan_payload,struct vdec_aspectratioinfo * aspect_ratio_info)12132 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12133         OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate,
12134         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
12135         struct vdec_aspectratioinfo *aspect_ratio_info)
12136 {
12137     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
12138     struct msm_vidc_panscan_window *panscan_window;
12139     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
12140         return;
12141     }
12142     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
12143     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12144     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12145     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
12146     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
12147     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
12148     switch (picture_type) {
12149         case PICTURE_TYPE_I:
12150             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
12151             break;
12152         case PICTURE_TYPE_P:
12153             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
12154             break;
12155         case PICTURE_TYPE_B:
12156             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
12157             break;
12158         default:
12159             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
12160     }
12161     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
12162         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
12163     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
12164         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
12165     else if (drv_ctx.interlace == VDEC_InterlaceFrameTopFieldFirst)
12166         frame_info->interlaceType = OMX_QCOM_InterlaceFrameTopFieldFirst;
12167     else if (drv_ctx.interlace == VDEC_InterlaceFrameBottomFieldFirst)
12168         frame_info->interlaceType = OMX_QCOM_InterlaceFrameBottomFieldFirst;
12169     else
12170         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
12171     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
12172     frame_info->nConcealedMacroblocks = num_conceal_mb;
12173     frame_info->nRecoverySeiFlag = recovery_sei_flag;
12174     frame_info->nFrameRate = frame_rate;
12175     frame_info->nTimeStamp = time_stamp;
12176     frame_info->panScan.numWindows = 0;
12177     if (output_capability == V4L2_PIX_FMT_MPEG2) {
12178         if (m_disp_hor_size && m_disp_vert_size) {
12179             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
12180             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
12181         } else {
12182             frame_info->displayAspectRatio.displayHorizontalSize = 0;
12183             frame_info->displayAspectRatio.displayVerticalSize = 0;
12184         }
12185     }
12186 
12187     if (panscan_payload) {
12188         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
12189         panscan_window = &panscan_payload->wnd[0];
12190         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
12191             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
12192             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
12193             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
12194             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
12195             panscan_window++;
12196         }
12197     }
12198     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
12199     print_debug_extradata(extra);
12200 }
12201 
append_portdef_extradata(OMX_OTHER_EXTRADATATYPE * extra)12202 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12203 {
12204     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
12205     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
12206     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12207     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12208     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
12209     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
12210     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
12211     *portDefn = m_port_def;
12212     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
12213             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
12214             (unsigned int)portDefn->format.video.nFrameWidth,
12215             (unsigned int)portDefn->format.video.nStride,
12216             (unsigned int)portDefn->format.video.nSliceHeight);
12217 }
12218 
append_outputcrop_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_output_crop_payload * output_crop_payload)12219 void omx_vdec::append_outputcrop_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12220         struct msm_vidc_output_crop_payload *output_crop_payload) {
12221     extra->nSize = OMX_OUTPUTCROP_EXTRADATA_SIZE;
12222     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12223     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12224     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo;
12225     extra->nDataSize = sizeof(OMX_QCOM_OUTPUT_CROP);
12226     memcpy(extra->data, output_crop_payload, extra->nDataSize);
12227 
12228     print_debug_extradata(extra);
12229 }
12230 
append_framepack_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_s3d_frame_packing_payload * s3d_frame_packing_payload)12231 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12232         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
12233 {
12234     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
12235     if (18 * sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
12236         DEBUG_PRINT_ERROR("frame packing size mismatch");
12237         return;
12238     }
12239     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
12240     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12241     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12242     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
12243     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12244     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
12245     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12246     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
12247     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12248     memcpy(&framepack->id, s3d_frame_packing_payload,
12249         sizeof(struct msm_vidc_s3d_frame_packing_payload));
12250     memcpy(&m_frame_pack_arrangement, framepack,
12251         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
12252     print_debug_extradata(extra);
12253 }
12254 
append_qp_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_frame_qp_payload * qp_payload)12255 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12256             struct msm_vidc_frame_qp_payload *qp_payload)
12257 {
12258     OMX_QCOM_EXTRADATA_QP * qp = NULL;
12259     if (!qp_payload) {
12260         DEBUG_PRINT_ERROR("QP payload is NULL");
12261         return;
12262     }
12263     extra->nSize = OMX_QP_EXTRADATA_SIZE;
12264     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12265     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12266     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
12267     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
12268     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
12269     qp->nQP = qp_payload->frame_qp;
12270     qp->nQPSum = qp_payload->qp_sum;
12271     qp->nSkipQPSum = qp_payload->skip_qp_sum;
12272     qp->nSkipNumBlocks = qp_payload->skip_num_blocks;
12273     qp->nTotalNumBlocks = qp_payload->total_num_blocks;
12274     print_debug_extradata(extra);
12275 }
12276 
append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_frame_bits_info_payload * bits_payload)12277 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12278             struct msm_vidc_frame_bits_info_payload *bits_payload)
12279 {
12280     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
12281     if (!bits_payload) {
12282         DEBUG_PRINT_ERROR("bits info payload is NULL");
12283         return;
12284     }
12285     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
12286     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12287     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12288     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
12289     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
12290     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
12291     bits->frame_bits = bits_payload->frame_bits;
12292     bits->header_bits = bits_payload->header_bits;
12293     print_debug_extradata(extra);
12294 }
12295 
append_user_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_OTHER_EXTRADATATYPE * p_user)12296 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12297             OMX_OTHER_EXTRADATATYPE *p_user)
12298 {
12299     int userdata_size = 0;
12300     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
12301     userdata_payload =
12302         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
12303     userdata_size = p_user->nDataSize;
12304     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
12305     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12306     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12307     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
12308     extra->nDataSize = userdata_size;
12309     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
12310         memcpy(extra->data, p_user->data, extra->nDataSize);
12311     print_debug_extradata(extra);
12312 }
12313 
append_terminator_extradata(OMX_OTHER_EXTRADATATYPE * extra)12314 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12315 {
12316     if (!client_extradata) {
12317         return;
12318     }
12319     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
12320     extra->nVersion.nVersion = OMX_SPEC_VERSION;
12321     extra->eType = OMX_ExtraDataNone;
12322     extra->nDataSize = 0;
12323     extra->data[0] = 0;
12324 
12325     print_debug_extradata(extra);
12326 }
12327 
allocate_desc_buffer(OMX_U32 index)12328 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
12329 {
12330     OMX_ERRORTYPE eRet = OMX_ErrorNone;
12331     if (index >= drv_ctx.ip_buf.actualcount) {
12332         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
12333         return OMX_ErrorInsufficientResources;
12334     }
12335     if (m_desc_buffer_ptr == NULL) {
12336         m_desc_buffer_ptr = (desc_buffer_hdr*) \
12337                     calloc( (sizeof(desc_buffer_hdr)),
12338                             drv_ctx.ip_buf.actualcount);
12339         if (m_desc_buffer_ptr == NULL) {
12340             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
12341             return OMX_ErrorInsufficientResources;
12342         }
12343     }
12344 
12345     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
12346     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
12347         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
12348         return OMX_ErrorInsufficientResources;
12349     }
12350 
12351     return eRet;
12352 }
12353 
insert_demux_addr_offset(OMX_U32 address_offset)12354 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
12355 {
12356     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
12357     if (m_demux_entries < 8192) {
12358         m_demux_offsets[m_demux_entries++] = address_offset;
12359     }
12360     return;
12361 }
12362 
extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE * buf_hdr)12363 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
12364 {
12365     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
12366     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
12367     OMX_U32 index = 0;
12368 
12369     m_demux_entries = 0;
12370 
12371     while (index < bytes_to_parse) {
12372         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12373                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
12374                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12375                  (buf[index+2] == 0x01)) ) {
12376             //Found start code, insert address offset
12377             insert_demux_addr_offset(index);
12378             if (buf[index+2] == 0x01) // 3 byte start code
12379                 index += 3;
12380             else                      //4 byte start code
12381                 index += 4;
12382         } else
12383             index++;
12384     }
12385     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
12386     return;
12387 }
12388 
handle_demux_data(OMX_BUFFERHEADERTYPE * p_buf_hdr)12389 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
12390 {
12391     //fix this, handle 3 byte start code, vc1 terminator entry
12392     OMX_U8 *p_demux_data = NULL;
12393     OMX_U32 desc_data = 0;
12394     OMX_U32 start_addr = 0;
12395     OMX_U32 nal_size = 0;
12396     OMX_U32 suffix_byte = 0;
12397     OMX_U32 demux_index = 0;
12398     OMX_U32 buffer_index = 0;
12399 
12400     if (m_desc_buffer_ptr == NULL) {
12401         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
12402         return OMX_ErrorBadParameter;
12403     }
12404 
12405     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
12406     if (buffer_index > drv_ctx.ip_buf.actualcount) {
12407         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
12408         return OMX_ErrorBadParameter;
12409     }
12410 
12411     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
12412 
12413     if ( ((OMX_U8*)p_demux_data == NULL) ||
12414             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
12415         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
12416         return OMX_ErrorBadParameter;
12417     } else {
12418         for (; demux_index < m_demux_entries; demux_index++) {
12419             desc_data = 0;
12420             start_addr = m_demux_offsets[demux_index];
12421             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
12422                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
12423             } else {
12424                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
12425             }
12426             if (demux_index < (m_demux_entries - 1)) {
12427                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
12428             } else {
12429                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
12430             }
12431             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
12432                     (unsigned int)start_addr,
12433                     (unsigned int)suffix_byte,
12434                     (unsigned int)nal_size,
12435                     (unsigned int)demux_index);
12436             desc_data = (start_addr >> 3) << 1;
12437             desc_data |= (start_addr & 7) << 21;
12438             desc_data |= suffix_byte << 24;
12439 
12440             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
12441             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
12442             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
12443             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
12444 
12445             p_demux_data += 16;
12446         }
12447         //Add zero word to indicate end of descriptors
12448         memset(p_demux_data, 0, sizeof(OMX_U32));
12449 
12450         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
12451         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
12452     }
12453     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
12454     m_demux_entries = 0;
12455     DEBUG_PRINT_LOW("Demux table complete!");
12456     return OMX_ErrorNone;
12457 }
12458 
enable_color_conversion(bool enable)12459 void omx_vdec::allocate_color_convert_buf::enable_color_conversion(bool enable) {
12460     if (!omx) {
12461         DEBUG_PRINT_HIGH("Invalid omx_vdec");
12462         return;
12463     }
12464 
12465     if (!omx->in_reconfig)
12466         enabled = enable;
12467 
12468     omx->c2d_enable_pending = enable;
12469 }
12470 
allocate_color_convert_buf()12471 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
12472 {
12473     enabled = false;
12474     client_buffers_disabled = false;
12475     omx = NULL;
12476     init_members();
12477     ColorFormat = OMX_COLOR_FormatMax;
12478     dest_format = YCbCr420P;
12479     m_c2d_width = 0;
12480     m_c2d_height = 0;
12481 
12482     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][-1] =
12483                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
12484     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][VDEC_CODECTYPE_MVC] =
12485                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
12486     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_UBWC][-1] =
12487                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
12488     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_TP10_UBWC][-1] =
12489                      QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
12490     mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_P010_VENUS][-1] =
12491                      QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus;
12492 
12493     mMapOutput2Convert.insert( {
12494             {VDEC_YUV_FORMAT_NV12, NV12_128m},
12495             {VDEC_YUV_FORMAT_NV12_UBWC, NV12_UBWC},
12496             {VDEC_YUV_FORMAT_NV12_TP10_UBWC, TP10_UBWC},
12497             {VDEC_YUV_FORMAT_P010_VENUS, YCbCr420_VENUS_P010},
12498         });
12499 }
12500 
set_vdec_client(void * client)12501 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
12502 {
12503     omx = reinterpret_cast<omx_vdec*>(client);
12504 }
12505 
init_members()12506 void omx_vdec::allocate_color_convert_buf::init_members()
12507 {
12508     allocated_count = 0;
12509     buffer_size_req = 0;
12510     buffer_alignment_req = 0;
12511     m_c2d_width = m_c2d_height = 0;
12512     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
12513     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
12514     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
12515     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
12516 #ifdef USE_ION
12517     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
12518 #endif
12519     for (int i = 0; i < MAX_COUNT; i++)
12520         pmem_fd[i] = -1;
12521 }
12522 
update_buffer_req()12523 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
12524 {
12525     bool status = true;
12526     unsigned int src_size = 0, destination_size = 0;
12527     unsigned int height, width;
12528     struct v4l2_format fmt;
12529     OMX_COLOR_FORMATTYPE drv_color_format;
12530 
12531     if (!omx) {
12532         DEBUG_PRINT_ERROR("Invalid client in color convert");
12533         return false;
12534     }
12535     if (!enabled) {
12536         DEBUG_PRINT_HIGH("No color conversion required");
12537         return true;
12538     }
12539     pthread_mutex_lock(&omx->c_lock);
12540 
12541     ColorSubMapping::const_iterator
12542         found =  mMapOutput2Convert.find(omx->drv_ctx.output_format);
12543     if (found == mMapOutput2Convert.end()) {
12544         DEBUG_PRINT_HIGH("%s: Could not find the color conversion "
12545                          "mapping for %#X. Setting to default NV12",
12546                          __func__, omx->drv_ctx.output_format);
12547         src_format = NV12_128m;
12548     } else {
12549         src_format = (ColorConvertFormat) found->second;;
12550     }
12551 
12552     memset(&fmt, 0x0, sizeof(struct v4l2_format));
12553     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
12554     fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
12555     ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
12556     width = fmt.fmt.pix_mp.width;
12557     height =  fmt.fmt.pix_mp.height;
12558 
12559     bool resolution_upgrade = (height > m_c2d_height ||
12560             width > m_c2d_width);
12561     bool is_interlaced = omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
12562     if (resolution_upgrade) {
12563         // resolution upgraded ? ensure we are yet to allocate;
12564         // failing which, c2d buffers will never be reallocated and bad things will happen
12565         if (allocated_count > 0) {
12566             DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
12567                     allocated_count);
12568             status = false;
12569         }
12570     }
12571 
12572     if (status != false) {
12573         if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
12574             (ColorFormat != OMX_COLOR_FormatYUV420Planar &&
12575              ColorFormat != OMX_COLOR_FormatYUV420SemiPlanar &&
12576              ColorFormat != (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12577             DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
12578             status = false;
12579         } else {
12580             ColorSubMapping::const_iterator
12581                 found =  mMapOutput2Convert.find(
12582                                                  omx->drv_ctx.output_format);
12583             if (found == mMapOutput2Convert.end()) {
12584                 src_format = NV12_128m;
12585             } else {
12586                 src_format = (ColorConvertFormat) found->second;;
12587             }
12588 
12589             DEBUG_PRINT_INFO("C2D: Set Resolution, Interlace(%s) Conversion(%#X -> %#X)"
12590                              " src(%dX%d) dest(%dX%d)",
12591                              (omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) ? "true": "false",
12592                              src_format, dest_format, width,
12593                              omx->m_progressive !=
12594                                   MSM_VIDC_PIC_STRUCT_PROGRESSIVE?(height+1)/2 : height,
12595                              width, height);
12596             status = c2dcc.setResolution(width,
12597                                          omx->m_progressive !=
12598                                          MSM_VIDC_PIC_STRUCT_PROGRESSIVE?
12599                                          (height+1)/2 : height,
12600                                          width, height,
12601                                          src_format, dest_format,
12602                                          0,0);
12603             if (status) {
12604                 src_size = c2dcc.getBuffSize(C2D_INPUT);
12605                 destination_size = c2dcc.getBuffSize(C2D_OUTPUT);
12606 
12607                 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
12608                     !destination_size) {
12609                     DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
12610                                       "driver size %u destination size %d",
12611                                       src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
12612                                       destination_size);
12613                     buffer_size_req = 0;
12614                     // TODO: make this fatal. Driver is not supposed to quote size
12615                     //  smaller than what C2D needs !!
12616                 } else {
12617                     buffer_size_req = destination_size;
12618                     m_c2d_height = height;
12619                     m_c2d_width = width;
12620                 }
12621             }
12622         }
12623     }
12624     pthread_mutex_unlock(&omx->c_lock);
12625     return status;
12626 }
12627 
set_color_format(OMX_COLOR_FORMATTYPE dest_color_format)12628 bool omx_vdec::allocate_color_convert_buf::set_color_format(
12629         OMX_COLOR_FORMATTYPE dest_color_format)
12630 {
12631     bool status = true, drv_colorformat_c2d_enable = false;
12632     bool dest_color_format_c2d_enable = false;
12633     OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused;
12634     if (!omx) {
12635         DEBUG_PRINT_ERROR("Invalid client in color convert");
12636         return false;
12637     }
12638     pthread_mutex_lock(&omx->c_lock);
12639     status = get_color_format (drv_color_format);
12640 
12641     drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) &&
12642         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12643                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
12644         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12645                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed) &&
12646         (drv_color_format != (OMX_COLOR_FORMATTYPE)
12647                 QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus);
12648 
12649     dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
12650             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
12651             (dest_color_format != (OMX_COLOR_FORMATTYPE)
12652                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
12653 
12654     if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) {
12655         DEBUG_PRINT_LOW("Enabling C2D");
12656         if (dest_color_format == OMX_COLOR_FormatYUV420Planar ||
12657             dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar ||
12658             ((omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE ||
12659             omx->eCompressionFormat == OMX_VIDEO_CodingMPEG2) &&
12660             dest_color_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12661             ColorFormat = dest_color_format;
12662             if (dest_color_format == OMX_COLOR_FormatYUV420Planar) {
12663                    dest_format = YCbCr420P;
12664             } else if( dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar) {
12665                     dest_format = YCbCr420SP;
12666             } else {
12667                    dest_format = NV12_128m;
12668             }
12669             enable_color_conversion(true);
12670         } else {
12671             DEBUG_PRINT_ERROR("Unsupported output color format for c2d (%d)",
12672                               dest_color_format);
12673             status = false;
12674             enable_color_conversion(false);
12675         }
12676     } else {
12677         enable_color_conversion(false);
12678     }
12679     pthread_mutex_unlock(&omx->c_lock);
12680     return status;
12681 }
12682 
get_il_buf_hdr(OMX_BUFFERHEADERTYPE * bufadd)12683 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
12684 (OMX_BUFFERHEADERTYPE *bufadd)
12685 {
12686     if (!omx) {
12687         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
12688         return NULL;
12689     }
12690     if (!is_color_conversion_enabled())
12691         return bufadd;
12692 
12693     OMX_BUFFERHEADERTYPE  *omx_base_address =
12694               is_color_conversion_enabled()?
12695                     omx->m_intermediate_out_mem_ptr:omx->m_out_mem_ptr;
12696 
12697     unsigned index = 0;
12698     index = bufadd - omx_base_address;
12699     if (index < omx->drv_ctx.op_buf.actualcount) {
12700         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12701         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
12702 
12703         omx->m_out_mem_ptr[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12704         omx->m_out_mem_ptr[index].nTimeStamp = bufadd->nTimeStamp;
12705         bool status = false;
12706         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
12707             pthread_mutex_lock(&omx->c_lock);
12708             omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12709 
12710             DEBUG_PRINT_INFO("C2D: Start color convertion");
12711             status = c2dcc.convertC2D(
12712                              omx->drv_ctx.ptr_intermediate_outputbuffer[index].pmem_fd,
12713                              bufadd->pBuffer, bufadd->pBuffer,
12714                              omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
12715                              omx->m_out_mem_ptr[index].pBuffer,
12716                              omx->m_out_mem_ptr[index].pBuffer);
12717             omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12718             if (!status) {
12719                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
12720                 m_out_mem_ptr_client[index].nFilledLen = 0;
12721                 omx->m_out_mem_ptr[index].nFilledLen = 0;
12722                 pthread_mutex_unlock(&omx->c_lock);
12723                 return &omx->m_out_mem_ptr[index];
12724             } else {
12725                 unsigned int filledLen = 0;
12726                 c2dcc.getBuffFilledLen(C2D_OUTPUT, filledLen);
12727                 if (filledLen > omx->m_out_mem_ptr[index].nAllocLen) {
12728                     DEBUG_PRINT_ERROR("Invalid C2D FBD length filledLen = %d alloclen = %d ",filledLen,omx->m_out_mem_ptr[index].nAllocLen);
12729                     filledLen = 0;
12730                 }
12731                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
12732                 omx->m_out_mem_ptr[index].nFilledLen = filledLen;
12733             }
12734             pthread_mutex_unlock(&omx->c_lock);
12735         } else {
12736             m_out_mem_ptr_client[index].nFilledLen = 0;
12737             omx->m_out_mem_ptr[index].nFilledLen = 0;
12738         }
12739         return &omx->m_out_mem_ptr[index];
12740     }
12741     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
12742     return NULL;
12743 }
12744 
get_buffer_req(unsigned int & buffer_size)12745     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
12746 (unsigned int &buffer_size)
12747 {
12748     bool status = true;
12749     pthread_mutex_lock(&omx->c_lock);
12750      /* Whenever port mode is set to kPortModeDynamicANWBuffer, Video Frameworks
12751         always uses VideoNativeMetadata and OMX receives buffer type as
12752         grallocsource via storeMetaDataInBuffers_l API. The buffer_size
12753         will be communicated to frameworks via IndexParamPortdefinition. */
12754     if (!enabled)
12755         buffer_size = omx->dynamic_buf_mode ? sizeof(struct VideoNativeMetadata) :
12756                       omx->drv_ctx.op_buf.buffer_size;
12757     else {
12758         buffer_size = c2dcc.getBuffSize(C2D_OUTPUT);
12759     }
12760     pthread_mutex_unlock(&omx->c_lock);
12761     return status;
12762 }
12763 
set_buffer_req(OMX_U32 buffer_size,OMX_U32 actual_count)12764 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
12765         OMX_U32 buffer_size, OMX_U32 actual_count)
12766 {
12767     OMX_U32 expectedSize = is_color_conversion_enabled() ? buffer_size_req : omx->dynamic_buf_mode ?
12768             sizeof(struct VideoDecoderOutputMetaData) : omx->drv_ctx.op_buf.buffer_size;
12769     if (buffer_size < expectedSize) {
12770         DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
12771                 buffer_size, expectedSize);
12772         return OMX_ErrorBadParameter;
12773     }
12774     if (actual_count < omx->drv_ctx.op_buf.mincount) {
12775         DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
12776                 actual_count, omx->drv_ctx.op_buf.mincount);
12777         return OMX_ErrorBadParameter;
12778     }
12779 
12780     if (enabled) {
12781         // disallow changing buffer size/count while we have active allocated buffers
12782         if (allocated_count > 0) {
12783             DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
12784                     buffer_size_req, buffer_size, allocated_count);
12785             return OMX_ErrorInvalidState;
12786         }
12787 
12788         buffer_size_req = buffer_size;
12789     } else {
12790         if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
12791             omx->drv_ctx.op_buf.buffer_size = buffer_size;
12792         }
12793     }
12794 
12795     omx->drv_ctx.op_buf.actualcount = actual_count;
12796     omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
12797     omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
12798             omx->drv_ctx.extradata_info.buffer_size;
12799     return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
12800 }
12801 
is_component_secure()12802 bool omx_vdec::is_component_secure()
12803 {
12804     return secure_mode;
12805 }
12806 
get_color_format(OMX_COLOR_FORMATTYPE & dest_color_format)12807 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
12808 {
12809     bool status = true;
12810     if (!enabled) {
12811         for (auto& x: mMapOutput2DriverColorFormat) {
12812             DecColorMapping::const_iterator
12813                 found = mMapOutput2DriverColorFormat.find(omx->drv_ctx.output_format);
12814             if (found == mMapOutput2DriverColorFormat.end()) {
12815                 status = false;
12816             } else {
12817                 ColorSubMapping::const_iterator
12818                     subFound = found->second.find(omx->drv_ctx.decoder_format);
12819                 if (subFound == found->second.end()) {
12820                     dest_color_format = (OMX_COLOR_FORMATTYPE)
12821                                              found->second.find(-1)->second;
12822                 } else {
12823                     dest_color_format = (OMX_COLOR_FORMATTYPE) subFound->second;
12824                 }
12825             }
12826         }
12827     } else {
12828         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
12829             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
12830             ColorFormat == (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
12831             dest_color_format = ColorFormat;
12832         } else {
12833             status = false;
12834         }
12835     }
12836     return status;
12837 }
12838 
send_codec_config()12839 void omx_vdec::send_codec_config() {
12840     if (codec_config_flag) {
12841         unsigned long p1 = 0, p2 = 0;
12842         unsigned long p3 = 0, p4 = 0;
12843         unsigned long ident = 0, ident2 = 0;
12844         pthread_mutex_lock(&m_lock);
12845         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
12846         while (m_etb_q.m_size) {
12847             m_etb_q.pop_entry(&p1,&p2,&ident);
12848             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
12849                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12850                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
12851                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12852                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
12853                         omx_report_error();
12854                     }
12855                 } else {
12856                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
12857                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
12858                 }
12859             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
12860                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12861                     while (m_ftb_q.m_size) {
12862                         m_ftb_q.pop_entry(&p3,&p4,&ident2);
12863                         if (ident2 == OMX_COMPONENT_GENERATE_FTB) {
12864                             pthread_mutex_unlock(&m_lock);
12865                             if (fill_this_buffer_proxy((OMX_HANDLETYPE)p3,\
12866                                         (OMX_BUFFERHEADERTYPE *)p4) != OMX_ErrorNone) {
12867                                 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
12868                                 omx_report_error ();
12869                             }
12870                             pthread_mutex_lock(&m_lock);
12871                         } else if (ident2 == OMX_COMPONENT_GENERATE_FBD) {
12872                             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p3);
12873                         }
12874                     }
12875                     pthread_mutex_unlock(&m_lock);
12876                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
12877                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12878                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
12879                         omx_report_error ();
12880                     }
12881                 } else {
12882                     pending_input_buffers++;
12883                     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
12884                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
12885                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
12886                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
12887                 }
12888             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
12889                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
12890                         (OMX_BUFFERHEADERTYPE *)p1);
12891                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
12892             }
12893         }
12894         pthread_mutex_unlock(&m_lock);
12895     }
12896 }
12897 
perf_control()12898 omx_vdec::perf_control::perf_control()
12899 {
12900     m_perf_control_enable = 0;
12901     m_perf_lib = NULL;
12902     m_perf_handle = 0;
12903     m_perf_lock_acquire = NULL;
12904     m_perf_lock_release = NULL;
12905 }
12906 
~perf_control()12907 omx_vdec::perf_control::~perf_control()
12908 {
12909     if (!m_perf_control_enable)
12910         return;
12911 
12912     if (m_perf_handle && m_perf_lock_release) {
12913         m_perf_lock_release(m_perf_handle);
12914         DEBUG_PRINT_LOW("perflock released");
12915     }
12916     if (m_perf_lib) {
12917         dlclose(m_perf_lib);
12918     }
12919 }
12920 
perf_lock_acquire()12921 int omx_vdec::perf_control::perf_lock_acquire()
12922 {
12923     int arg[2];
12924     if (!m_perf_control_enable)
12925         return 0;
12926 
12927     if (!m_perf_lib) {
12928         DEBUG_PRINT_ERROR("no perf control library");
12929         return -1;
12930     }
12931     if (!m_perf_lock_acquire) {
12932         DEBUG_PRINT_ERROR("NULL perflock acquire");
12933         return -1;
12934     }
12935     if (m_perf_handle) {
12936         DEBUG_PRINT_LOW("perflock already acquired");
12937         return 0;
12938     }
12939     DEBUG_PRINT_HIGH("perflock acquire");
12940     arg[0] = MPCTLV3_VIDEO_DECODE_PB_HINT;
12941     arg[1] = 1;
12942     m_perf_handle = m_perf_lock_acquire(0, 0, arg, sizeof(arg) / sizeof(int));
12943     if (m_perf_handle < 0) {
12944         DEBUG_PRINT_ERROR("perflock acquire failed with error %d", m_perf_handle);
12945         m_perf_handle = 0;
12946         return -1;
12947     }
12948     return 0;
12949 }
12950 
perf_lock_release()12951 void omx_vdec::perf_control::perf_lock_release()
12952 {
12953     if (!m_perf_control_enable)
12954         return;
12955 
12956     if (!m_perf_lib) {
12957         DEBUG_PRINT_ERROR("no perf control library");
12958         return;
12959     }
12960     if (!m_perf_lock_release) {
12961         DEBUG_PRINT_ERROR("NULL perflock release");
12962         return;
12963     }
12964     if (!m_perf_handle) {
12965         DEBUG_PRINT_LOW("perflock already released");
12966         return;
12967     }
12968     DEBUG_PRINT_HIGH("perflock release");
12969     m_perf_lock_release(m_perf_handle);
12970     m_perf_handle = 0;
12971 }
12972 
load_perf_library()12973 bool omx_vdec::perf_control::load_perf_library()
12974 {
12975     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
12976 
12977     if (!m_perf_control_enable) {
12978         DEBUG_PRINT_HIGH("perf control is not enabled");
12979         return false;
12980     }
12981     if (m_perf_lib) {
12982         DEBUG_PRINT_HIGH("perf lib already opened");
12983         return true;
12984     }
12985 
12986     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
12987         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
12988         goto handle_err;
12989     }
12990 
12991     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
12992         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
12993         goto handle_err;
12994     } else {
12995         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
12996         if (m_perf_lock_acquire == NULL) {
12997             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
12998             goto handle_err;
12999         }
13000         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
13001         if (m_perf_lock_release == NULL) {
13002             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
13003             goto handle_err;
13004         }
13005     }
13006     return true;
13007 
13008 handle_err:
13009     if (m_perf_lib) {
13010         dlclose(m_perf_lib);
13011     }
13012     m_perf_lib = NULL;
13013     m_perf_lock_acquire = NULL;
13014     m_perf_lock_release = NULL;
13015     return false;
13016 }
13017 
enable_adaptive_playback(unsigned long nMaxFrameWidth,unsigned long nMaxFrameHeight)13018 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
13019                             unsigned long nMaxFrameHeight)
13020 {
13021 
13022     OMX_ERRORTYPE eRet = OMX_ErrorNone;
13023     int ret = 0;
13024     unsigned long min_res_buf_count = 0;
13025 
13026     eRet = enable_smoothstreaming();
13027     if (eRet != OMX_ErrorNone) {
13028          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
13029          return eRet;
13030      }
13031 
13032      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
13033              nMaxFrameWidth,
13034              nMaxFrameHeight);
13035      m_smoothstreaming_mode = true;
13036      m_smoothstreaming_width = nMaxFrameWidth;
13037      m_smoothstreaming_height = nMaxFrameHeight;
13038 
13039      //Get upper limit buffer count for min supported resolution
13040      struct v4l2_format fmt;
13041      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
13042      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
13043      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
13044      fmt.fmt.pix_mp.pixelformat = output_capability;
13045 
13046      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
13047      if (ret) {
13048          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
13049                            m_decoder_capability.min_height,
13050                            m_decoder_capability.min_width);
13051          return OMX_ErrorUnsupportedSetting;
13052      }
13053 
13054      eRet = get_buffer_req(&drv_ctx.op_buf);
13055      if (eRet != OMX_ErrorNone) {
13056          DEBUG_PRINT_ERROR("failed to get_buffer_req");
13057          return eRet;
13058      }
13059 
13060      min_res_buf_count = drv_ctx.op_buf.mincount;
13061      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
13062                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
13063 
13064      m_extradata_info.output_crop_rect.nLeft = 0;
13065      m_extradata_info.output_crop_rect.nTop = 0;
13066      m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width;
13067      m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height;
13068 
13069      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
13070                        m_smoothstreaming_width, m_smoothstreaming_height);
13071 
13072      //Get upper limit buffer size for max smooth streaming resolution set
13073      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
13074      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
13075      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
13076      fmt.fmt.pix_mp.pixelformat = output_capability;
13077      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
13078      if (ret) {
13079          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
13080          return OMX_ErrorUnsupportedSetting;
13081      }
13082 
13083      eRet = get_buffer_req(&drv_ctx.op_buf);
13084      if (eRet != OMX_ErrorNone) {
13085          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
13086          return eRet;
13087      }
13088      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
13089                      (unsigned int)drv_ctx.op_buf.buffer_size);
13090 
13091      drv_ctx.op_buf.mincount = min_res_buf_count;
13092      drv_ctx.op_buf.actualcount = min_res_buf_count;
13093      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
13094      eRet = set_buffer_req(&drv_ctx.op_buf);
13095      if (eRet != OMX_ErrorNone) {
13096          DEBUG_PRINT_ERROR("failed to set_buffer_req");
13097          return eRet;
13098      }
13099 
13100      eRet = get_buffer_req(&drv_ctx.op_buf);
13101      if (eRet != OMX_ErrorNone) {
13102          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
13103          return eRet;
13104      }
13105      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
13106                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
13107      return eRet;
13108 }
13109 
13110 //static
describeColorFormat(OMX_PTR pParam)13111 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
13112 
13113 #ifndef FLEXYUV_SUPPORTED
13114     return OMX_ErrorUndefined;
13115 #else
13116 
13117     if (pParam == NULL) {
13118         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
13119         return OMX_ErrorBadParameter;
13120     }
13121 
13122     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
13123 
13124     MediaImage *img = &(params->sMediaImage);
13125     switch(params->eColorFormat) {
13126         case static_cast <OMX_COLOR_FORMATTYPE> (QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m):
13127         {
13128             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
13129             img->mNumPlanes = 3;
13130             // mWidth and mHeight represent the W x H of the largest plane
13131             // In our case, this happens to be the Stride x Scanlines of Y plane
13132             img->mWidth = params->nFrameWidth;
13133             img->mHeight = params->nFrameHeight;
13134             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13135             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
13136             img->mBitDepth = 8;
13137             //Plane 0 (Y)
13138             img->mPlane[MediaImage::Y].mOffset = 0;
13139             img->mPlane[MediaImage::Y].mColInc = 1;
13140             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
13141             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
13142             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
13143             //Plane 1 (U)
13144             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
13145             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
13146             img->mPlane[MediaImage::U].mRowInc =
13147                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13148             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
13149             img->mPlane[MediaImage::U].mVertSubsampling = 2;
13150             //Plane 2 (V)
13151             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
13152             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
13153             img->mPlane[MediaImage::V].mRowInc =
13154                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
13155             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
13156             img->mPlane[MediaImage::V].mVertSubsampling = 2;
13157             break;
13158         }
13159 
13160         case OMX_COLOR_FormatYUV420Planar:
13161         case OMX_COLOR_FormatYUV420SemiPlanar:
13162             // We need not describe the standard OMX linear formats as these are
13163             // understood by client. Fail this deliberately to let client fill-in
13164             return OMX_ErrorUnsupportedSetting;
13165 
13166         default:
13167             // Rest all formats which are non-linear cannot be described
13168             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
13169             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
13170             return OMX_ErrorNone;
13171     };
13172 
13173     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
13174     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
13175     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
13176     for (size_t i = 0; i < img->mNumPlanes; ++i) {
13177         DEBUG_PRINT_LOW("  Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
13178                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
13179     }
13180     return OMX_ErrorNone;
13181 #endif //FLEXYUV_SUPPORTED
13182 }
13183 
prefetch_buffers(unsigned long prefetch_count,unsigned long prefetch_size,unsigned ioctl_code,unsigned ion_flag)13184 bool omx_vdec::prefetch_buffers(unsigned long prefetch_count,
13185         unsigned long prefetch_size, unsigned ioctl_code, unsigned ion_flag)
13186 {
13187     struct ion_prefetch_data prefetch_data;
13188     struct ion_prefetch_regions regions;
13189     __u64 sizes[prefetch_count];
13190     int rc, ion_fd = ion_open();
13191     if (ion_fd < 0) {
13192         DEBUG_PRINT_ERROR("%s: Ion fd open failed : %d", __func__, ion_fd);
13193         return false;
13194     }
13195 
13196     DEBUG_PRINT_HIGH("%s: prefetch_count : %lu, prefetch_size : %lu, ioctl : %u",
13197             __func__, prefetch_count, prefetch_size, ioctl_code);
13198     for (uint32_t i = 0; i < prefetch_count; i++) {
13199         sizes[i] = prefetch_size;
13200     }
13201 
13202     regions.nr_sizes = prefetch_count;
13203 #if TARGET_ION_ABI_VERSION >= 2
13204     regions.sizes = (__u64)sizes;
13205 #else
13206     regions.sizes = sizes;
13207 #endif
13208     regions.vmid = ion_flag;
13209 
13210     prefetch_data.nr_regions = 1;
13211 #if TARGET_ION_ABI_VERSION >= 2
13212     prefetch_data.regions = (__u64)&regions;
13213 #else
13214     prefetch_data.regions = &regions;
13215 #endif
13216     prefetch_data.heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
13217 
13218     rc = ioctl(ion_fd, ioctl_code, &prefetch_data);
13219     if (rc) {
13220         DEBUG_PRINT_ERROR("%s: Prefetch ioctl failed ioctl : %u, rc : %d, errno : %d",
13221                 __func__, ioctl_code, rc, errno);
13222         rc = false;
13223     } else {
13224         rc = true;
13225     }
13226 
13227     close(ion_fd);
13228     return rc;
13229 }
13230 
store_vp9_hdr10plusinfo(DescribeHDR10PlusInfoParams * hdr10plusdata)13231 bool omx_vdec::store_vp9_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13232 {
13233     struct hdr10plusInfo metadata;
13234 
13235     if (!hdr10plusdata) {
13236         DEBUG_PRINT_ERROR("hdr10plus info not present");
13237         return false;
13238     }
13239 
13240     if (hdr10plusdata->nParamSize > MAX_HDR10PLUSINFO_SIZE ||
13241             hdr10plusdata->nParamSize < 1) {
13242         DEBUG_PRINT_ERROR("Invalid hdr10plus metadata size %u", hdr10plusdata->nParamSize);
13243         return false;
13244     }
13245 
13246     if (output_capability != V4L2_PIX_FMT_VP9) {
13247         DEBUG_PRINT_ERROR("DescribeHDR10PlusInfoParams is not supported for %d codec",
13248             output_capability);
13249         return false;
13250     }
13251 
13252     memset(&metadata, 0, sizeof(struct hdr10plusInfo));
13253     metadata.nSize = hdr10plusdata->nSize;
13254     metadata.nVersion = hdr10plusdata->nVersion;
13255     metadata.nPortIndex = hdr10plusdata->nPortIndex;
13256     metadata.nParamSize = hdr10plusdata->nParamSize;
13257     metadata.nParamSizeUsed = hdr10plusdata->nParamSizeUsed;
13258     memcpy(metadata.payload, hdr10plusdata->nValue , hdr10plusdata->nParamSizeUsed);
13259     metadata.is_new = true;
13260 
13261     /*
13262      * For the first setconfig, set the timestamp as zero. For
13263      * the remaining, set the timestamp equal to previous
13264      * etb timestamp + 1 to know this hdr10plus data arrived
13265      * after previous etb.
13266      */
13267     if (m_etb_count) {
13268         metadata.timestamp = m_etb_timestamp + 1;
13269     }
13270 
13271     pthread_mutex_lock(&m_hdr10pluslock);
13272     DEBUG_PRINT_LOW("add hdr10plus info to the list with timestamp %lld and size %u",
13273         metadata.timestamp, metadata.nParamSizeUsed);
13274     m_hdr10pluslist.push_back(metadata);
13275     pthread_mutex_unlock(&m_hdr10pluslock);
13276 
13277     return true;
13278 }
13279 
store_hevc_hdr10plusinfo(uint32_t payload_size,msm_vidc_stream_userdata_payload * hdr10plusdata)13280 bool omx_vdec::store_hevc_hdr10plusinfo(uint32_t payload_size,
13281     msm_vidc_stream_userdata_payload *hdr10plusdata)
13282 {
13283     struct hdr10plusInfo metadata;
13284 
13285     if (!hdr10plusdata) {
13286         DEBUG_PRINT_ERROR("hdr10plus info not present");
13287         return false;
13288     }
13289 
13290     if (payload_size > MAX_HDR10PLUSINFO_SIZE ||
13291             payload_size < 1) {
13292         DEBUG_PRINT_ERROR("Invalid hdr10plus metadata size %u", payload_size);
13293         return false;
13294     }
13295 
13296     if (output_capability != V4L2_PIX_FMT_HEVC) {
13297         DEBUG_PRINT_ERROR("msm_vidc_stream_userdata_payload is not supported for %d codec",
13298             output_capability);
13299         return false;
13300     }
13301 
13302     memset(&metadata, 0, sizeof(struct hdr10plusInfo));
13303     metadata.nParamSizeUsed = payload_size;
13304     memcpy(metadata.payload, hdr10plusdata->data , payload_size);
13305     metadata.is_new = true;
13306     if (m_etb_count) {
13307         metadata.timestamp = m_etb_timestamp + 1;
13308     }
13309 
13310     pthread_mutex_lock(&m_hdr10pluslock);
13311     DEBUG_PRINT_LOW("add hevc hdr10plus info to the list with size %u", payload_size);
13312     m_hdr10pluslist.push_back(metadata);
13313     pthread_mutex_unlock(&m_hdr10pluslock);
13314 
13315     return true;
13316 }
13317 
update_hdr10plusinfo_cookie_using_timestamp(OMX_PTR markdata,OMX_TICKS timestamp)13318 void omx_vdec::update_hdr10plusinfo_cookie_using_timestamp(OMX_PTR markdata, OMX_TICKS timestamp)
13319 {
13320     std::list<hdr10plusInfo>::reverse_iterator iter;
13321     unsigned int found = 0;
13322     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13323     bool is_list_empty = false;
13324 
13325     if (output_capability != V4L2_PIX_FMT_VP9 &&
13326         output_capability != V4L2_PIX_FMT_HEVC)
13327         return;
13328 
13329     pthread_mutex_lock(&m_hdr10pluslock);
13330     is_list_empty = m_hdr10pluslist.empty();
13331     pthread_mutex_unlock(&m_hdr10pluslock);
13332 
13333     if (is_list_empty) {
13334         DEBUG_PRINT_HIGH("update_hdr10plusinfo_cookie_using_timestamp: hdr10plusinfo list is empty!");
13335         return;
13336     }
13337     /*
13338      * look for the hdr10plus data which has timestamp nearest and
13339      * lower than the etb timestamp, we should not take the
13340      * hdr10plus data which has the timestamp greater than etb timestamp.
13341      */
13342     pthread_mutex_lock(&m_hdr10pluslock);
13343     iter = m_hdr10pluslist.rbegin();
13344     while (iter != m_hdr10pluslist.rend()) {
13345         if (iter->timestamp <= timestamp && iter->is_new) {
13346             found++;
13347             if (found == 1) {
13348                 iter->cookie = cookie;
13349                 iter->is_new = false;
13350                 DEBUG_PRINT_LOW("Cookie value %u stored in hdr10plus list with timestamp %lld, size %u",
13351                     iter->cookie, iter->timestamp, iter->nParamSizeUsed);
13352             }
13353         }
13354         iter++;
13355     }
13356     pthread_mutex_unlock(&m_hdr10pluslock);
13357 
13358     if(found > 1)
13359         DEBUG_PRINT_HIGH("Multiple hdr10plus data not expected. Continue with the latest");
13360 }
13361 
convert_hdr10plusinfo_to_metadata(OMX_PTR markdata,ColorMetaData & colorData)13362 void omx_vdec::convert_hdr10plusinfo_to_metadata(OMX_PTR markdata, ColorMetaData &colorData)
13363 {
13364     std::list<hdr10plusInfo>::iterator iter;
13365     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13366     bool is_list_empty = false;
13367 
13368     if (output_capability != V4L2_PIX_FMT_VP9 &&
13369         output_capability != V4L2_PIX_FMT_HEVC)
13370         return;
13371 
13372     pthread_mutex_lock(&m_hdr10pluslock);
13373     is_list_empty = m_hdr10pluslist.empty();
13374     pthread_mutex_unlock(&m_hdr10pluslock);
13375 
13376     if (is_list_empty) {
13377         DEBUG_PRINT_HIGH("convert_hdr10plusinfo_to_metadata: hdr10plusinfo list is empty!");
13378         return;
13379     }
13380 
13381     pthread_mutex_lock(&m_hdr10pluslock);
13382     iter = m_hdr10pluslist.begin();
13383     while (iter != m_hdr10pluslist.end()) {
13384         if (iter->cookie == cookie && !iter->is_new) {
13385             colorData.dynamicMetaDataValid = true;
13386             colorData.dynamicMetaDataLen = iter->nParamSizeUsed;
13387             memcpy(colorData.dynamicMetaDataPayload, iter->payload,
13388                 iter->nParamSizeUsed);
13389             DEBUG_PRINT_LOW("found hdr10plus metadata for cookie %u with timestamp %lld, size %u",
13390                 cookie, iter->timestamp, colorData.dynamicMetaDataLen);
13391             break;
13392         }
13393         iter++;
13394     }
13395     pthread_mutex_unlock(&m_hdr10pluslock);
13396 }
13397 
remove_hdr10plusinfo_using_cookie(OMX_PTR markdata)13398 void omx_vdec::remove_hdr10plusinfo_using_cookie(OMX_PTR markdata)
13399 {
13400     std::list<hdr10plusInfo>::iterator iter;
13401     unsigned int cookie = (unsigned int)(unsigned long)markdata;
13402     bool is_list_empty = false;
13403 
13404     if (output_capability != V4L2_PIX_FMT_VP9 &&
13405         output_capability != V4L2_PIX_FMT_HEVC)
13406         return;
13407 
13408     pthread_mutex_lock(&m_hdr10pluslock);
13409     is_list_empty = m_hdr10pluslist.empty();
13410     pthread_mutex_unlock(&m_hdr10pluslock);
13411 
13412     if (is_list_empty) {
13413         DEBUG_PRINT_HIGH("remove_hdr10plusinfo_using_cookie: hdr10plusinfo list is empty!");
13414         return;
13415     }
13416 
13417     pthread_mutex_lock(&m_hdr10pluslock);
13418     iter = m_hdr10pluslist.begin();
13419     while (iter != m_hdr10pluslist.end()) {
13420         if (iter->cookie == cookie && !iter->is_new) {
13421             iter = m_hdr10pluslist.erase(iter);
13422             DEBUG_PRINT_LOW("removed hdr10plusinfo from the list for the cookie %u", cookie);
13423             break;
13424         }
13425         iter++;
13426     }
13427     pthread_mutex_unlock(&m_hdr10pluslock);
13428 }
13429 
clear_hdr10plusinfo()13430 void omx_vdec::clear_hdr10plusinfo()
13431 {
13432     bool is_list_empty = false;
13433 
13434     if (output_capability != V4L2_PIX_FMT_VP9 &&
13435         output_capability != V4L2_PIX_FMT_HEVC)
13436         return;
13437 
13438     pthread_mutex_lock(&m_hdr10pluslock);
13439     is_list_empty = m_hdr10pluslist.empty();
13440     pthread_mutex_unlock(&m_hdr10pluslock);
13441 
13442     if (is_list_empty) {
13443         DEBUG_PRINT_HIGH("clear_hdr10plusinfo: hdr10plusinfo list is empty!");
13444         return;
13445     }
13446 
13447     pthread_mutex_lock(&m_hdr10pluslock);
13448     m_hdr10pluslist.clear();
13449     pthread_mutex_unlock(&m_hdr10pluslock);
13450 }
13451 
get_hdr10plusinfo(DescribeHDR10PlusInfoParams * hdr10plusdata)13452 void omx_vdec::get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13453 {
13454     std::list<hdr10plusInfo>::iterator iter;
13455     bool is_list_empty = false;
13456 
13457     if (output_capability != V4L2_PIX_FMT_VP9 &&
13458         output_capability != V4L2_PIX_FMT_HEVC)
13459         return;
13460 
13461     pthread_mutex_lock(&m_hdr10pluslock);
13462     is_list_empty = m_hdr10pluslist.empty();
13463     pthread_mutex_unlock(&m_hdr10pluslock);
13464 
13465     if (is_list_empty) {
13466         DEBUG_PRINT_HIGH("get_hdr10plusinfo: hdr10plusinfo list is empty!");
13467         return;
13468     }
13469 
13470     pthread_mutex_lock(&m_hdr10pluslock);
13471     iter = m_hdr10pluslist.begin();
13472     while (iter != m_hdr10pluslist.end()) {
13473         if (!iter->is_new) {
13474             hdr10plusdata->nParamSizeUsed = iter->nParamSizeUsed;
13475             memcpy(hdr10plusdata->nValue, iter->payload,
13476                 iter->nParamSizeUsed);
13477             DEBUG_PRINT_LOW("found hdr10plus metadata with timestamp %lld, size %u",
13478                 iter->timestamp, iter->nParamSizeUsed);
13479             iter = m_hdr10pluslist.erase(iter);
13480             break;
13481         }
13482         iter++;
13483     }
13484     pthread_mutex_unlock(&m_hdr10pluslock);
13485 }
13486 
print_hdr10plusinfo(DescribeHDR10PlusInfoParams * hdr10plusdata)13487 void omx_vdec::print_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
13488 {
13489          DEBUG_PRINT_LOW("HDR10+ frameworks path valid data length: %d", hdr10plusdata->nParamSizeUsed);
13490         for (uint32_t i = 0 ; i < hdr10plusdata->nParamSizeUsed && i+3 < 1024; i=i+4) {
13491             DEBUG_PRINT_LOW("HDR10+ mdata: %02X %02X %02X %02X", hdr10plusdata->nValue[i],
13492             hdr10plusdata->nValue[i+1],
13493             hdr10plusdata->nValue[i+2],
13494             hdr10plusdata->nValue[i+3]);
13495     }
13496 }
13497 
13498 // No code beyond this !
13499 
13500 // inline import of vendor-extensions implementation
13501 #include "omx_vdec_extensions.hpp"
13502